Из комментария в другой ответ:
Я был на самом деле искал способ реализовать Group By First Character в Джанго ОРМ
Я хотел бы сделать это в следующих 3 шага:
Аннотировать каждую запись первой буквой поля name
. Для этого можно использовать функцию Substr
вместе с Lower
from django.db.models.functions import Substr, Lower
qs = User.objects.annotate(fl_name=Lower(Substr('name', 1, 1)))
Следующая, группа все записи с первой буквы и получить количество идентификаторов. Это может быть сделано с помощью annotate with values:
# 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'))
Далее, вы можете заказать эту QuerySet с первой буквы:
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')
На e nd, ваш запрос будет выглядеть примерно так. Обратите внимание, что я преобразовал первый символ в нижний регистр при аннотации. Если вам это не нужно, вы можете удалить 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}
Итак, как мы можем помочь? –
@MosesKoledoye Мне нужно оптимизировать это и, возможно, сделать его одним запросом, используя функцию 'values ()' – samix73
Эта группа не имеет никакого смысла? Если вы группируете первую букву имени каждого пользователя, вы получите только 26 записей, это то, что вы ищете? – e4c5