Django prefetch_通过关系与m2m相关联 [英] Django prefetch_related with m2m through relationship
问题描述
我有以下模型
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)
A 电影
(星球大战:克隆战争)有几个 Person
(Christopher Lee),每个人都可以有一个或多个角色
Dooku Count of Count Dooku)和每个角色
有一个 RoleType
(Voice actor)。
A Film
("Star Wars: The Clone Wars") has several Person
("Christopher Lee"), each one of them can have one or more Role
("Voice of Count Dooku") and every Role
has a RoleType
("Voice actor").
我正在使用DetailView显示电影
I'm using a DetailView to display the Film
class FilmDetail(DetailView):
model = Film
在我的模板中,我显示所有的人,所以每次我看电影正在执行609个查询。为了减少这个,我想使用 prefetch_related
,所以我将视图更改为:
In my template i'm showing all the Persons, so each time I show a Film 609 queries are being executed. To reduce this I want to use prefetch_related
so I changed the view to:
class FilmDetail(DetailView):
model = Film
def get_queryset(self):
return super(FilmDetail, self).get_queryset().prefetch_related('crew')
但是这并没有减少查询次数(610),我尝试了以下参数预取相关,它没有工作:
But this didn't reduce the number of queries(610), I tried the following parameters to prefetch related and it didn't work:
def get_queryset(self):
return super(FilmDetail, self).get_queryset().prefetch_related('crew__person_role')
我有一个不能在Person对象上找到'person_role','crew__person_role'是prefetch_related()的无效参数
错误
我可以如何预取 Person.full_name
和 slug
和所有角色
字段来自 Film.crew
?
What can I do to prefetch the Person.full_name
and slug
and all Role
fields from Film.crew
?
推荐答案
Yo你可以像这样构建你的查询:
You can construct your queryset like this:
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
加载的转发关系。
Only Film->Role is a backwards relation loadable with prefetch_related
. Role->RoleType and Role->Person are forwards relations that you load with select_related
.
这篇关于Django prefetch_通过关系与m2m相关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!