且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Django与经理相关的重复查询

更新时间: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