我有以下型号
class Film(models.Model):
crew = models.ManyToManyField('Person', through='Role', blank=True)
class Role(models.Model):
person = models.ForeignKey('Person')
film = models.ForeignKey('Film')
person_role = models.ForeignKey(RoleType)
credit = models.CharField(max_length=200)
credited_as = models.CharField(max_length=100)
class RoleType(models.Model):
"""Actor, director, makeup artist..."""
name = models.CharField(max_length=50)
class Person(models.Model):
slug = models.SlugField(max_length=30, unique=True, null=True)
full_name = models.CharField(max_length=255)
一个
Film
(“星球大战:克隆人 war ”)有几个Person
(“克里斯托弗·李”),他们每个人可以有一个或多个Role
(“杜库伯爵之声”),并每Role
有RoleType
(“声优”)。我正在使用 DetailView 来显示
Film
class FilmDetail(DetailView):
model = Film
在我的模板中,我显示了所有人员,因此每次我显示 Film 时都会执行 609 查询。为了减少这种情况,我想使用
prefetch_related
所以我将 View 更改为:class FilmDetail(DetailView):
model = Film
def get_queryset(self):
return super(FilmDetail, self).get_queryset().prefetch_related('crew')
但这并没有减少查询的数量(610),我尝试了以下参数来预取相关,但没有用:
def get_queryset(self):
return super(FilmDetail, self).get_queryset().prefetch_related('crew__person_role')
我收到了
Cannot find 'person_role' on Person object, 'crew__person_role' is an invalid parameter to prefetch_related()
错误我该怎么做才能从
Person.full_name
中预取 slug
和 Role
以及所有 Film.crew
字段? 最佳答案
您可以像这样构造查询集:
from django.db.models import Prefetch
def get_queryset(self):
return super(FilmDetail, self).get_queryset().prefetch_related(
Prefetch(
'crew',
queryset=Role.objects.select_related(
'person',
'person_role',
),
),
)
只有 Film->Role 是可加载
prefetch_related
的反向关系。 Role->RoleType 和 Role->Person 是您使用 select_related
加载的转发关系。关于Django prefetch_related 与 m2m 通过关系,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35093204/