Django admin pages: Can queryset extra fields be used for sorting specific columns

2.2k Views Asked by At

So, the extra field in a queryset can be used to add additional columns to your select query, which in turn can be set as the default ordering. I have so far been able to achieve this: created an extra field and then set it as default ordering.

qs = qs.extra(select={'natname':"concat('0', nat, name)"}, order_by=['natname'])

Now, in my admin interface, I have my other fields {name, nat, location, space, ....} and the results from the table are ordered by natname when the page is loaded...perfect.

But now I wish to enable ordering on the name field, but instead of ordering by name, I want it to order it by natname. Is this possible?

So even though natname is an extra field, I want to somehow bind the column name with natname when it comes to ordering.

Right now, if I do qs.query.__str__(), I get the sql query with order by natname. When I click on the column name, order by changes to name, but just for this special case, I wish it to order it by natname. Is this possible?

I have looked at how Django generates the headers and the views for these automated admin pages under <django-installation-path>/contrib/admin but it only references the list_display set defined in the ModelAdmin for this model. If I make any changes there, the columns displayed get changed in the admin-view.

It might sound a bit confusing. If you require particular details, please feel free to ask.

Thanks.

1

There are 1 best solutions below

15
On BEST ANSWER

Yes! this is possible (at least in Django 1.2.3):

In your admin.ModelAdmin subclass:

from django.contrib import admin

from .models import ClassA

class ModelAdminA(admin.ModelAdmin):
    list_display = ('natname',)

    def natname(self, obj):
        return obj.name
    natname.admin_order_field = 'natname'
    natname.short_description = 'name'

    def queryset(self, request):
        qs = super(ModelAdminA, self).queryset(request)
        qs = qs.extra(select={ 'natname': "concat('0', nat, name)" })
        return qs

admin.site.register(ClassA, ModelAdminA)