链式外键上的 Django select_related
Django select_related on chained foreign keys
我在这里阅读了文档和所有相关问题,但我没有正确理解 select_related 在 chained/multiple 外键上的行为方式。
假设我们有以下模型:
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. 我们如何在
中使用 select_related
Producer.objects.filter(...).select_related(?)
查询以便预加载所有内容?会不会像:
Producer.objects.filter(...).select_related(
'customer__record_label', 'customer__belongs_to_band')
为什么?
B. 如果 class Band 有 'Genre' 作为外键,
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')
对于问题A:
将参数作为字符串传递
qs = Producer.objects.filter(...).select_related(
'customer__record_label', '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, ...)
到select所有相关模型(做一个大连接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 语句的基本概念;这应该让您了解它所做的联接。
如果您在查询时遇到问题,那么您应该添加更多信息,了解具体情况和您的预期。
我在这里阅读了文档和所有相关问题,但我没有正确理解 select_related 在 chained/multiple 外键上的行为方式。
假设我们有以下模型:
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. 我们如何在
中使用 select_relatedProducer.objects.filter(...).select_related(?)
查询以便预加载所有内容?会不会像:
Producer.objects.filter(...).select_related(
'customer__record_label', 'customer__belongs_to_band')
为什么?
B. 如果 class Band 有 'Genre' 作为外键,
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')
对于问题A: 将参数作为字符串传递
qs = Producer.objects.filter(...).select_related(
'customer__record_label', '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, ...)
到select所有相关模型(做一个大连接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 语句的基本概念;这应该让您了解它所做的联接。
如果您在查询时遇到问题,那么您应该添加更多信息,了解具体情况和您的预期。