From a comment in another answer:
I was really looking for a way to implement Group By First Character in django orm
I would do this in the following three steps:
Annotate each entry with the first letter of the name field. For this you can use Substr together with Lower
from django.db.models.functions import Substr, Lower qs = User.objects.annotate(fl_name=Lower(Substr('name', 1, 1)))
Then group all the records with this first letter and get the number of identifiers. This can be done using annotate values :
# since, we annotated each record we can use the first letter for grouping, and
Then you can order this set of queries with the first letter:
qs = qs.order_by('fl_name')
Combining all this in one statement:
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')
At the end, your request will look something like this. Notice that I converted the first character to lowercase on annotation. If you do not need this, you can remove the Lower function:
[{'fl_name': 'a', 'cnt_users': 12}, {'fl_name': 'b', 'cnt_users': 4}, ... ... {'fl_name': 'z', 'cnt_users': 3},]
If you need a dictionary with a letter and a counter:
fl_count = dict(qs.values('fl_name', 'cnt_users')) # {'a': 12, 'b': 4, ........., 'z': 3}
source share