Search code examples
djangodjango-ormdistinct-values

Django - How to annotate count() of distinct values


I have the following model:

class Bank(model.Model):
    name: models.CharField
    ....

Using the following sample data:

╔══════════════╗
║ Row ID, Name ║
╠══════════════╣
║ 1, ABC       ║
║ 2, ABC       ║
║ 3, XYZ       ║
║ 4, MNO       ║
║ 5, ABC       ║
║ 6, DEF       ║
║ 7, DEF       ║
╚══════════════╝

I want to extract distinct bank names like so:

[('ABC', 3), ('XYZ', 1), ('MNO', 1), ('DEF', 2)]

I have tried using annotate and distict but the following error is being raised:

NotImplementedError: annotate() + distinct(fields) is not implemented.

I've also come accross the following question on SO:

Question 1

Which has answers on using models.Count('name', distinct=True) but it's returning duplicate values. How can I handle this using Django ORM?


Solution

  • Arakkal Abu's Answer worked for some rows, but was returning some duplicates. I have no idea why, but I added the following to his suggestion:

    qs = Bank.objects.values('name').annotate(count=Count('id')).order_by('name').distinct()
    

    Which made me realize that the exception raised said: distinct(fields) is not implemented, not distinct().

    Also, on @ruddra's input on using Count('name') instead of Count('id'), I have not seen the difference between them. They all returned same results.

    So the following worked too:

    qs = Bank.objects.values('name').annotate(count=Count('name')).order_by('name').distinct()