我的应用中Unit
每周都会创建Order
和Report
,我希望在第一列中查看结果为包含Unit
s名称的表格在接下来的6列中有3个最新的Order
和Report
s。所以我需要查询单位和3个相关的订单和报告到每个单位。
我尝试以这种方式使用prefetch_related
,但不知道如何限制它(甚至让它工作)
Unit.objects.filter(parent__name__contains="x").prefetch_related('order_set', 'reportfrom_set').order_by('order__date','reportfrom__submit_datetime')
提前致谢
答案 0 :(得分:0)
prefetch_related()
方法将为您要预取的每个查找执行数据库查询。基本上,在这里,Django将执行第一个数据库查询以获取Unit
个实例,然后执行另外两个查询以获取Order
和Report
实例。
因此,一旦执行了Unit.obects.filter(...).prefetch_related(...)
查询集,每个Unit
实例将缓存其相关的Order
和Report
对象(不再需要数据库查询来获取这些数据)。
自Django 1.7起,prefetch_related()
方法接受Prefetch
对象。此Prefetch
对象具有queryset
属性,可帮助您过滤/订购相关对象:
from django.shortcuts import render_to_response
def my_view(request):
units = Unit.objects.all().prefetch_related(
Prefetch(
'orders_set',
queryset=Order.objects.all().order_by('date'),
to_attr='prefetched_orders'
),
Prefetch(
'report_set',
queryset=Report.objects.all().order_by('submit_datetime'),
to_attr='prefetched_reports'
)
)
for unit in units:
unit.prefetched_orders = unit.prefetched_orders[:3]
unit.prefetched_reports = unit.prefetched_reports[:3]
return render_to_response('template.html', context={
'units': units
})
to_attr
属性允许我们将相关对象存储在Python list
中。
因此,slicing这些列表将不再调用数据库。
现在您拥有最新的订单和报告,您可以构建所需的对象。
您可以像这样迭代你的单位(units
集合是模板上下文的units
对象):
{% for unit in units %}
...
{% endfor %}
然后,您可以浏览以前预取的对象(使用此代码的表格设计):
<table>
{% for unit in units %}
<tr>
<td>{{ unit.field_to_display }}</td>
{% for order in unit.prefetched_orders %}
<td>{{ order.field_to_display}}</td>
{% endfor %}
{% for report in unit.prefetched_reports %}
<td>{{ report.field_to_display}}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
有关模板语言的更多信息,请参阅official doc。