我查询一个模型:
Members.objects.all()
然后返回:
Eric, Salesman, X-Shop
Freddie, Manager, X2-Shop
Teddy, Salesman, X2-Shop
Sean, Manager, X2-Shop
我想知道向数据库激发group_by
查询的最佳Django方法,例如:
Members.objects.all().group_by('designation')
当然,这是行不通的。 我知道我们可以在django/db/models/query.py
上做一些小技巧,但我只是很好奇知道如何在不打补丁的情况下做。
如果您打算进行聚合,则可以使用ORM的聚合特性:
from django.db.models import Count
Members.objects.values('designation').annotate(dcount=Count('designation'))
这将导致类似于
SELECT designation, COUNT(designation) AS dcount
FROM members GROUP BY designation
输出的形式为
[{'designation': 'Salesman', 'dcount': 2},
{'designation': 'Manager', 'dcount': 2}]
一个简单的解决方案,但不是正确的方法是使用原始SQL:
results = Members.objects.raw('SELECT * FROM myapp_members GROUP BY designation')
另一种解决方案是使用group_by
属性:
query = Members.objects.all().query
query.group_by = ['designation']
results = QuerySet(query=query, model=Members)
现在可以迭代results变量来检索结果。 请注意,group_by
没有文档化,可能会在Django的未来版本中进行更改。
然后。。。 为什么要使用group_by
? 如果不使用聚合,可以使用order_by
来实现类似的结果。
还可以使用regroup
模板标记按属性分组。 从文档中:
cities = [
{'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
{'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
{'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
{'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
{'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
]
...
{% regroup cities by country as country_list %}
<ul>
{% for country in country_list %}
<li>{{ country.grouper }}
<ul>
{% for city in country.list %}
<li>{{ city.name }}: {{ city.population }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
看起来是这样的:
我相信它也适用于queryset
。
来源:https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#regroup
编辑:请注意,如果词典列表不是按键排序的,regroup
标记将无法正常工作。 它以迭代的方式工作。 因此,在将列表(或查询集)传递给regroup
标记之前,按石斑鱼的键对其进行排序。