【问题标题】:How to prefetch_related fields for a related field in Django如何为Django中的相关字段预取相关字段
【发布时间】:2021-08-15 13:09:20
【问题描述】:

我似乎有一些示例说明如何在 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')
    )
)

如何预取所有相关内容?

【问题讨论】:

    标签: django django-models prefetch django-select-related


    【解决方案1】:

    应该可以:

    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
    
     
    

    【讨论】:

      猜你喜欢
      • 2013-05-11
      • 1970-01-01
      • 1970-01-01
      • 2021-10-19
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-06
      相关资源
      最近更新 更多