Python 使用django优化queryset
我创建了一个函数,允许计算状态的数量并将其分配给变量Python 使用django优化queryset,python,django,python-3.x,query-optimization,django-queryset,Python,Django,Python 3.x,Query Optimization,Django Queryset,我创建了一个函数,允许计算状态的数量并将其分配给变量 def get_types_count_display(self): dispatches = self.route_dispatches.values_list('dispatch_id', flat=True) dispatches = Dispatch.objects.filter(id__in=dispatches) d = { "dispatches_types": list(dispatches.value
def get_types_count_display(self):
dispatches = self.route_dispatches.values_list('dispatch_id', flat=True)
dispatches = Dispatch.objects.filter(id__in=dispatches)
d = { "dispatches_types": list(dispatches.values('status_id')) }
pendents = len([1 for e in d["dispatches_types"] if e["status_id"]==1])
delivered = len([1 for e in d["dispatches_types"] if e["status_id"]==2])
partial = len([1 for e in d["dispatches_types"] if e["status_id"]==3])
undelivered = len([1 for e in d["dispatches_types"] if e["status_id"]==4])
return dict(pendents=pendents, delivered=delivered, partial=partial, undelivered=undelivered)
其中d是存储它所包含的字典的变量
{'dispatches_types': [{'status_id': 2}, {'status_id': 1}, {'status_id': 1}, {'status_id': 1}, {'status_id': 2}]}
或
这是动态的
我遇到的问题是,当您再次调用查询集时,查询会变得更重
如何优化此功能?为此,您应该使用
聚合是一个dict,其值与您之前返回的值相同,但对于您可以使用的“较少”查询,使用1个查询执行。给出的示例实际上正是您想要做的 如果分派记录的总数相对较少,则通过调用queryset上的.value并对其进行过滤,将其作为字典一次加载到内存中,这可能比在每个循环中获取记录块更快。我经常这样做,尤其是当它意味着避免模型对象的实例化时
-看来我太慢了 如前所述,条件聚合在这里可能更有效。只是想添加替代查询,因为我们实际上不需要获取总和聚合,而是需要获取具有指定状态的调度计数。因此,可以用以下方式编写:
from django.db.models import Q
aggregates = dispatches.aggregate(
pendents=Count('pk', filter=Q(status_id=1)),
delivered =Count('pk', filter=Q(status_id=2)),
partial=Count('pk', filter=Q(status_id=3)),
undelivered=Count('pk', filter=Q(status_id=4)),
)
谢谢你试着用这种方式,但还是要问几个问题你在说什么?您是否在一个请求中多次调用get\u types\u count\u display?谢谢!!我曾经尝试过这种方法,它也会进行同样数量的查询:/n如果不知道反复调用get\u types\u count\u display的方法/循环,我们就无法真正帮助您。使用聚合可以为您提供最小数量的查询。是的,同样的想法,但它提供相同数量的咨询谢谢!!我试过这种方法,但它也会发出同样数量的查询:/这很奇怪。。根据Django文档,这应该转化为一个带有计数和case语句的查询。
from django.db import IntegerField, Sum, Case, When
def get_types_count_display(self):
dispatches self.route_dispatches.all()
aggregates = dispatches.aggregate(
pendents=Sum(Case(When(status_id=1, then=1), output_field=IntegerField())),
delivered =Sum(Case(When(status_id=2, then=1), output_field=IntegerField())),
partial=Sum(Case(When(status_id=3, then=1), output_field=IntegerField())),
undelivered=Sum(Case(When(status_id=4, then=1), output_field=IntegerField()))
)
return aggregates
from django.db.models import Q
aggregates = dispatches.aggregate(
pendents=Count('pk', filter=Q(status_id=1)),
delivered =Count('pk', filter=Q(status_id=2)),
partial=Count('pk', filter=Q(status_id=3)),
undelivered=Count('pk', filter=Q(status_id=4)),
)