我试图按name
每个记录的字段的字符对记录进行分组,并限制每个组中的项目,这是我想出的:
desired_letters = ['a','b','c',..,'z']
some_variable = {}
for desired_letter in desired_letters:
some_variable += User.objects.all().order_by("name").filter(name__startswith=desired_letter)[:10]
而且我在for循环中运行此查询并更改desired_letter
为所需的字母,还有其他方法可以优化此解决方案并使它成为单个查询而不是for循环吗?
从另一个答案中的注释中:
我实际上正在寻找一种在Django Orm中实施按首字符分组的方法
我会按照以下3个步骤进行操作:
用name
字段的第一个字母注释每个记录。为此,您可以将Substr
function与Lower
from django.db.models.functions import Substr, Lower
qs = User.objects.annotate(fl_name=Lower(Substr('name', 1, 1)))
接下来,使用第一个字母将所有记录分组,并获取ID计数。这可以通过使用带有值的注释来完成:
# since, we annotated each record we can use the first letter for grouping, and
# then get the count of ids for each group
from django.db.models import Count
qs = qs.values('fl_name').annotate(cnt_users=Count('id'))
接下来,您可以使用第一个字母对这个查询集进行排序:
qs = qs.order_by('fl_name')
将所有这些合并为一个语句:
from django.db.models.functions import Substr, Lower
from django.db.models import Count
qs = User.objects \
.annotate(fl_name=Lower(Substr('name', 1, 1))) \
.values('fl_name') \
.annotate(cnt_users=Count('id')) \
.order_by('fl_name')
最后,您的查询集将如下所示。请注意,我在注释时将第一个字符转换为小写。如果不需要,可以删除该Lower
功能:
[{'fl_name': 'a', 'cnt_users': 12},
{'fl_name': 'b', 'cnt_users': 4},
...
...
{'fl_name': 'z', 'cnt_users': 3},]
如果需要,则需要字母和数字的字典:
fl_count = dict(qs.values('fl_name', 'cnt_users'))
# {'a': 12, 'b': 4, ........., 'z': 3}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句