python - 预取相关的django

标签 python django django-queryset

我正在开发一个用 Django 编写的应用程序,我在使用 select_related 和 prefetch_related 执行正确请求时遇到了一些问题

我有三个模型:

class Intervention(BaseModel):
    date = DateField()
    housing = ForeignKey('contract.Housing', related_name='interventions')

class Housing(BaseModel):
    address = CharField(max_length=CHAR_FIELD_LENGTH) 

class Tenant(BaseModel):
    name = CharField(max_length=CHAR_FIELD_LENGTH)
    phone = CharField(max_length=CHAR_FIELD_LENGTH, blank=True, null=True)
    housing = ForeignKey(Housing, related_name='tenants')

我请求模型干预,如果我想访问住房信息,我只需要使用 select_related :

Interventions.object.select_related("housing").filter(...)

但我不知道如何使用 prefetch_related 访问租户:

Interventions.object.select_related("housing").prefetch_related("housing__tenants") 

似乎不起作用,因为每次我尝试访问租户列表时它都会进行查询。 有没有一种方法可以访问租户列表,最好是对 I 进行过滤(比如找到的第一个没有名字的租户)。

感谢您的回答。

阿尔杰罗斯

*编辑:这是一些代码:*

我像我说的那样请求:

interventionPreventivesVisits = InterventionPreventiveVisit.objects.select_related("housing").prefetch_related("housing__tenants").filter(date__range=(self.weekDays[0], self.weekDays[len(self.weekDays)-1]))

self.weekDays 是一个天数表,用于在日历中显示干预措施。

然后,我想显示没有名字的租户:

在我的模板中,我遍历干预:

{%for inter in interventions %}
    {%if day == inter.date %}
        {{ inter | get_schedule_html_formated | safe}}
    {%endif%}
{% endfor %}

我有一个 templateTag 来显示 HTML:

def get_schedule_html_formated(intervention):
    housingTenant = None
    for tenant in intervention.housing.tenants.all(): # Here it does a query
        if tenant.name is not None:
            housingTenant = tenant
    ....

然后我编写并返回我的 html

我正在寻找一种无需执行新查询即可设置 housingTenant 的方法。

这样更好吗:)?

最佳答案

从这里https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related

select_related works by creating an SQL join and including the fields of the related object in the SELECT statement. For this reason, select_related gets the related objects in the same database query. However, to avoid the much larger result set that would result from joining across a ‘many’ relationship, select_related is limited to single-valued relationships - foreign key and one-to-one.

prefetch_related, on the other hand, does a separate lookup for each relationship, and does the ‘joining’ in Python.

评论更新:

最好先在这里放置过滤器(django 中的顺序会影响结果):

interventionPreventivesVisits = InterventionPreventiveVisit.objects.filter(
    date__range=(self.weekDays[0], self.weekDays[len(self.weekDays)-1])
).select_related("housing"
).prefetch_related("housing__tenants")

关于python - 预取相关的django,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20347188/

相关文章:

python - 使用 django-axes 登录 Django

django - 模块未找到错误: No module named 'win32api' right after I install channels

mysql - Django:更大的查询集和小号。数据库命中率,反之亦然

django - 找出查询集的关系

python - Django 使用 icontains 过滤器来过滤字典中的多个值

python - 获取 Python 中整数所需的字节大小

python - 如何通过网络而不是可执行文件运行简单的脚本

python - 网页抓取 - Python;写入 CSV

python - OpenGL 基础 : calling glDrawElements once per object

django - MongoDB 实例停止在 Webfaction 上运行