Django prefetch_related与m2m通过关系

时间:2016-01-29 20:11:00

标签: django django-models django-queryset

我有以下型号

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预取slugRole以及所有Film.crew字段?

1 个答案:

答案 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加载的转发关系。

相关问题