Mounir Messelmeni
Mounir's blog

Follow

Mounir's blog

Follow
How to order a calculated count field in Django's admin

Photo by Sear Greyson on Unsplash

How to order a calculated count field in Django's admin

Mounir Messelmeni's photo
Mounir Messelmeni
·Mar 20, 2016·

1 min read

You can easily add a field which count a specific related model from a reverse ForeignKey relation or a ManyToMany relation, but ordering this field could not be easy from the first time.

Here we will see how to use annotate to add this field and how to order it. You only have to define admin_order_field as in the following.

A basic models example models.py:


    class Teacher(models.Model):
        name = models.CharField(max_length=255)

    class Student(models.Model):
        name = models.CharField(max_length=255)
        teacher = models.ForeignKey(Teacher)

And the admin.py


    @admin.register(Teacher)
    class TeacherAdmin(admin.ModelAdmin):
        list_display = (
            'id',
            'students_count',
        )

        def get_queryset(self, request):
            return Teacher.objects.annotate(students_count=Count('student'))

        def students_count(self, obj):
            return obj.students_count

        students_count.short_description = _('Students count')
        students_count.admin_order_field = 'students_count'

UPDATE (20/10/2022): With Django >= 3.2 you can use the new display decorator

    @admin.register(Teacher)
    class TeacherAdmin(admin.ModelAdmin):
        list_display = (
            'id',
            'students_count',
        )

        def get_queryset(self, request):
            return Teacher.objects.annotate(students_count=Count('student'))

        @admin.display(
            ordering='students_count',
            description=_('Students count'),
        )
        def students_count(self, obj):
            return obj.students_count
 
Share this