queryset中django计数特定行

queryset中django计数特定行,django,split,count,django-queryset,annotate,Django,Split,Count,Django Queryset,Annotate,我想显示特定用户的所有订单,但我想将它们分为“旧”订单和“旧”订单 因此,目前我在views.py中执行以下操作: class Order(models.Model): name = models.CharField(max_length=100) # other fields.. user = models.ForeginKey(User) old = models.BooleanField(default=False) 在模板中: 第一张表: orders = Or

我想显示特定用户的所有订单,但我想将它们分为“旧”订单和“旧”订单

因此,目前我在
views.py中执行以下操作:

class Order(models.Model):
   name = models.CharField(max_length=100)
   # other fields..
   user = models.ForeginKey(User)
   old = models.BooleanField(default=False)
在模板中:

第一张表:

orders = Order.objects.filter(user=user)
此模板代码是否生成一个或两个查询

class Order(models.Model):
   name = models.CharField(max_length=100)
   # other fields..
   user = models.ForeginKey(User)
   old = models.BooleanField(default=False)
   objects = CustomManager() # Custom manager


class CustomQueryset(models.QuerySet):
    def no_old(self):
        return self.filter(old=False)

class CustomManager(models.Manager):
    def get_queryset(self):
        return CustomQuerySet(model=self.model, using=self._db)

您不能进行任何注释,也不需要进行
.count()
,因为内存中已经有了所有数据。因此,它实际上只是介于:

{% if orders.no_old %}
{% for order orders.no_old %}
... 
{% endfor %}
{% endif %} 
在这个特定场景中,我认为不会有任何性能差异。就我个人而言,我会选择第二种方法来处理这两个问题

一本关于该问题的提示的好书:

更新 关于您介绍的自定义管理器。我认为你做得不对我认为你想要的是:

orders = Order.objects.filter(user=user)
old_orders = [o for o in orders if o.old]
new_orders = [o for o in orders if not o.old]

#or

old_orders = Order.objects.filter(user=user, old=True)
new_orders = Order.objects.filter(user=user, old=False)
因此:

class CustomQueryset(models.QuerySet):
    def no_old(self):
        return self.filter(old=False)

class Order(models.Model):
   name = models.CharField(max_length=100)
   # other fields..
   user = models.ForeginKey(User)
   old = models.BooleanField(default=False)

   #if you already have a manager
   #objects = CustomManager.from_queryset(CustomQueryset)()
   #if you dont:
   objects = CustomQueryset.as_manager()
如果执行
{%If orders.no_old%}
将执行另一个查询,因为
QuerySet
实例没有缓存

关于{%regroup%}标记
正如您所提到的,为了使用它,您需要
.order\u by('old')
,如果您有其他订单,您仍然可以使用它,只需在
old
之后应用您的订单,例如
.order\u by('old','other\u field')
。这样,您将只使用一个查询,这将在列表上为您节省一次迭代(因为Django将拆分列表,只对其进行一次迭代),但模板中的可读性将降低。

使用几乎相同的查询查询同一个表似乎很奇怪。。如果我只需要计算old=True的数量,没有显示它们。你还会做两个查询吗,一个是用.count()查询吗?我觉得更奇怪的是,一个列表只需重复两次就可以拆分了。然后在模板中再进行一次渲染。是的,如果我不需要这些记录到内存中,我将使用
.count()
。谢谢!我想我可能会使用一个定制的查询集/管理器,因为我想避免通过2个查询集。我在帖子中添加了一个编辑,你能分享你的观点吗?我明白了,但即使使用.as_manager(),我仍然认为它在模板中使用时会执行两个查询..可能会重复看到{%regroup%}标记,但问题是它没有按顺序输入。所以要使用它,我必须添加一个order_by('old'),我在这里不需要它。我的queryset上已经有订单了。不确定什么会有更好的性能,根据django文档,订购不是“免费的”。平均用户的订单量有多大?如果我们谈论的是每个用户5-10-50个订单,你真的不应该考虑哪种方法更好-2个查询集vs 2个迭代-节省时间做一些更重要的事情,因为它的大小可能在100左右,但这不是我需要以这种方式拆分它的唯一模型。我有大约5个相似的模型,我想把它们分成一个字段。如果现在或将来有机会引入分页,那么两个QuerySet是正确的(而且mb是唯一的)方法。
orders = Order.objects.filter(user=user)
old_orders = [o for o in orders if o.old]
new_orders = [o for o in orders if not o.old]

#or

old_orders = Order.objects.filter(user=user, old=True)
new_orders = Order.objects.filter(user=user, old=False)
class CustomQueryset(models.QuerySet):
    def no_old(self):
        return self.filter(old=False)

class Order(models.Model):
   name = models.CharField(max_length=100)
   # other fields..
   user = models.ForeginKey(User)
   old = models.BooleanField(default=False)

   #if you already have a manager
   #objects = CustomManager.from_queryset(CustomQueryset)()
   #if you dont:
   objects = CustomQueryset.as_manager()
orders = Order.objects.filter(user=user)