In my database model, I have last and first name. In the django-admin site, I want to display "Lastname, Firstname" and have this column sortable. For this, I'm using the @admin.display
decorator in my admin.ModelAdmin
class.
This decorator takes an ordering
parameter which can be a string, referencing a model field name to sort by, for example:
@admin.display(description = "Full name", ordering = "last_name")
def full_name(self, obj):
return f"{obj.last_name}, {obj.first_name}"
However, this will only sort by last_name
, obviously, and therefore people with the same last name will end up in arbitrary order. I've tried:
@admin.display(description = "Full name", ordering = ["last_name", "first_name"])
Or using a list instead of a tuple, but this fails ("'tuple' object has no attribute 'startswith'").
I searched for this and found my exact question unanswered here: https://forum.djangoproject.com/t/how-to-tell-admin-display-decorator-to-order-the-results-by-two-columns/21418 Also in this post: Django-admin order by multiple fields someone suggests that the intuitive list syntax would work with "ordering", but this does not seem to work inside the decorator.
Unfortunately that indeed does not work, I tried the same some time ago, and found out it was not implemented (that way). But for this specific case, you can just reproduce the behavior with Concat
[Django-doc], to concatenate the two fields together and produce a string, so as in the body of the function:
from django.db.models import Value
from django.db.models.functions import Concat
@admin.display(
description='Full name',
ordering=Concat('last_name', Value(','), 'first_name'),
)
def full_name(self, obj):
return f'{obj.last_name}, {obj.first_name}'