Django prefetch_通过关系与m2m相关联 [英] Django prefetch_related with m2m through relationship

查看:129
本文介绍了Django prefetch_通过关系与m2m相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下模型

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆