我在这里阅读了文档和所有相关问题,但是我没有正确理解 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/