我有以下型号
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
(“星球大战:克隆人战争”)有几个Person
(“克里斯托弗李”),每个人都可以有一个或多个Role
(“声音“杜库伯”中的每一个Role
都有一个RoleType
(“配音演员”)。
我正在使用DetailView来显示Film
class FilmDetail(DetailView):
model = Film
在我的模板中,我显示所有人,所以每次我显示一个电影609查询正在执行。为了减少这种情况,我想使用prefetch_related
,因此我将视图更改为:
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
字段?
答案 0 :(得分:7)
您可以像这样构建查询集:
UIReferenceLibraryViewController
仅限电影 - >角色是可以使用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',
),
),
)
加载的向后关系。 Role-> RoleType和Role-> Person是您使用prefetch_related
加载的转发关系。