如何为Django中的相关字段预取_related字段

问题描述

我似乎有一些关于如何在 Django 中的前向和后向关系中prefetch_related 字段的示例,但我怀疑如果我们想要预取相关字段的所有字段,如何应用此方法模型。

例如,如果我想从以下模型中获取所有内容,请使用 HealthCheck 作为起点。哪个是实现这一目标的最优化查询?

class HealthCheck(models.Model):
    id = models.Integer()
    person = models.ForeignKey('Person')


class Person(models.Model):
    profile = models.ForeignKey('Profile')
    vaccines = models.ManyToManyField('vaccines',through='PersonVaccines')


class Profile(models.Model):
    name = models.CharField(max_length=16)


class PersonVaccines(models.Model):
    person = models.ForeignKey(Person)
    vaccine = models.ForeignKey('Vaccine')


class Vaccine(models.Model):
    name = models.CharField(max_length=16)

我尝试过类似的方法,但似乎不起作用:

from django.db.models import Prefetch

HealthCheck.objects.filter(id=1).prefetch_related(
    Prefetch(
        'person__vaccines',queryset=PersonVaccines.objects.select_related('person','person__profile','vaccine')
    )
)

如何预取所有相关内容?

解决方法

应该可以:

HealthCheck.objects.filter(id=1).select_related('person__profile').prefetch_related('person__vaccines')

select_related 将获取所有相关字段,直到 profile

prefetch_related 然后应该预取所有相关对象,直到 vaccines

编辑:经过测试并确认,当我为一名健康检查人员创建 3 个疫苗对象时,仅生成了 2 个查询(n 是我对执行的查询进行计数的函数):

In [2]: health_check = HealthCheck.objects.filter(id=3).select_related('person__profile').prefetch_related('person__vaccines').get()
     ...:

In [3]: n()
2

In [4]: for v in health_check.person.vaccines.all():
     ...:     print(v.name)
     ...:
v1
v2
v3

In [5]: n()
0

 

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...