更新时间:2023-02-27 14:38:14
prefetch_related仅在使用 .all时有效。 ()
。
如果应用任何其他转换,如 .filter()
,将进行新的数据库查询。这是因为 prefetch_related
只是将所有相关实例缓存在列表中,因此Django无法在列表中执行 filter()
。要解决您的问题,您应该使用 Prefetch 对象。
您可以将 queryset
参数传递给它。因此,不要使用list_prefetch_related,而是在您的管理类中重写 get_queryset
方法。
prefetch_related only works when you use .all()
.
If you apply any other transformations like .filter()
, the new DB query will be made. This is because prefetch_related
simply caches ALL related instances in list, so Django cannot perform filter()
on list. To solve your issue you should use Prefetch object.
You can pass queryset
parametr to it. So, instead of using list_prefetch_related, override get_queryset
method in your admin class.
def get_queryset(*args, **kwargs):
qs = super().get_queryset(*args, **kwargs)
qs = qs.prefetch_related(Prefetch('c2app2_set', queryset=C2App2.objects.filter(is_ok=False)))
return qs
p>
And
class C1App1(WithDateAndOwner):
def get_c2_app2(self):
res = self.c2app2_set.all()
if res.count() > 0:
return res[0]
else:
return None