alg*_*los 4 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')
Run Code Online (Sandbox Code Playgroud)
我要求干预模型,如果要访问房屋信息,只需使用select_related:
Interventions.object.select_related("housing").filter(...)
Run Code Online (Sandbox Code Playgroud)
但是我不知道如何使用prefetch_related访问租户:
Interventions.object.select_related("housing").prefetch_related("housing__tenants")
Run Code Online (Sandbox Code Playgroud)
似乎不起作用,因为每次我尝试访问租户列表时都会进行查询。有没有一种方法可以访问租户列表,最好是对I进行过滤(例如找到第一个没有名称的租户)。
感谢您的回答。
阿尔盖洛斯
* 编辑:这是一些代码:*
我要求像我说的那样:
interventionPreventivesVisits = InterventionPreventiveVisit.objects.select_related("housing").prefetch_related("housing__tenants").filter(date__range=(self.weekDays[0], self.weekDays[len(self.weekDays)-1]))
Run Code Online (Sandbox Code Playgroud)
self.weekDays是一个天数表,用于在日历中显示干预。
然后,我要显示没有名称的承租人:
在我的模板中,我遍历干预:
{%for inter in interventions %}
{%if day == inter.date %}
{{ inter | get_schedule_html_formated | safe}}
{%endif%}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
我有一个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
....
Run Code Online (Sandbox Code Playgroud)
然后我写并返回我的html
我正在寻找一种无需做新查询即可设置HousingTenant的方法。
那个更好吗 :) ?
从这里https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related
select_related通过创建SQL连接并将相关对象的字段包括在SELECT语句中来工作。因此,select_related在同一数据库查询中获取相关对象。但是,为了避免跨“许多”关系进行联接会产生更大的结果集,select_related仅限于单值关系-外键和一对一关系。
另一方面,prefetch_related 对每个关系进行单独的查找,并在Python中进行“加入”。
更新评论:
最好先在此处放置过滤器(django中的顺序可能会影响结果):
interventionPreventivesVisits = InterventionPreventiveVisit.objects.filter(
date__range=(self.weekDays[0], self.weekDays[len(self.weekDays)-1])
).select_related("housing"
).prefetch_related("housing__tenants")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7749 次 |
| 最近记录: |