django - Django select_related链接的外键

标签 django django-queryset django-select-related

我在这里阅读了文档和所有相关问题,但是我没有正确理解 select_related 在链接/多个外键上的行为。

假设我们有以下模型:

class RecordLabel(models.Model):
   title = models.CharField(...)

class Band(models.Model):
   band_name = models.CharField(...)

class Artist(models.Model):
   record_label = models.ForeignKey(RecordLabel,...)
   belongs_to_band = models.ForeignKey(Band, ...)

class Producer(models.Model):
   customer = models.ForeignKey(Artist, ...)

A. 我们将如何在
Producer.objects.filter(...).select_related(?)

查询,以便一切都预先加载?会是这样的:
Producer.objects.filter(...).select_related(
    'customer__record_label', 'customer__belongs_to_band')

为什么呢?

B. 如果Band类具有“类型”作为外键,
 class Genre(models.Model):
       genre_name = models.CharField(...)        

 class Band(models.Model):
       band_name = models.CharField(...)
       music_genre = models.ForeignKey(Genres, ...)

然后,为了预先加载所有内容,我们将执行以下操作:
Producer.objects.filter(...).select_related(
    'customer__record_label__music_genre', 'customer__record_label__band_name',
    'customer__belongs_to_band__music_genre', 'customer__belongs_to_band__music_genre') 

或类似这样的东西:
Producer.objects.filter(...).select_related(
    'customer__record_label__music_genre', 'customer__record_label__band_name',
    'customer__belongs_to_band', 'customer__belongs_to_band') 

最佳答案

关于问题B:

如果我正确理解了您的问题,则只需指定一次字段,无需重复。

注意:我会在这里再次显示模型的最终版本,否则会引起混淆。

class RecordLabel(models.Model):
    title = models.CharField(...)

class Genre(models.Model):
    genre_name = models.CharField(...)

class Band(models.Model):
    band_name = models.CharField(...)
    music_genre = models.ForeignKey(Genre, ...)

class Artist(models.Model):
    record_label = models.ForeignKey(RecordLabel, ...)
    belongs_to_band = models.ForeignKey(Band, ...)

class Producer(models.Model):
    customer = models.ForeignKey(Artist, ...)

要选择所有相关模型(进行一个大的联接SQL查询):
qs = Producer.objects.filter(...).select_related(
    'customer__record_label',
    'customer__belongs_to_band__music_genre')

第一部分(customer)预获取相关艺术家和相关记录标签(__record_label);第二部分不需要获取艺术家,因为它已经存在,但是它继续预取了相关的乐团(__belongs_to_band)和相关的流派(__music_genre)。现在,您有了一个可以访问所有5个表(模型)的SQL查询。

提示:您可以使用 qs.query 来查看查询将生成的SQL语句的基本概念。这应该使您对其建立的连接有所了解。

如果查询存在问题,则应添加有关实际发生的情况和期望的更多信息。

关于django - Django select_related链接的外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52410178/

相关文章:

带有日期时间计算的 Django 查询集注释

python - 如何使用基于类的模型在 django 管理表单中制作自动完成过滤器

python - 具有存储在模型中的距离值的 GeoDjango 距离过滤器 - 查询

python - Django 模板变量解析

python - 运行脚本来填充 Django 数据库

python - 查询集花费太多时间

python - 来自 Django 中多个字段的唯一值的字典列表

django - 将Django从1.6升级到1.8 : Invalid field name(s) given in select_related

python - 如何将django admin中输入的时间转换为utc?