Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable sorting by primary key in Django Admin?

Django admin sorts by primary key in addition to sorting fields specified in the model "ordering" record, thus, making it necessary to have composite indexes on a model just to allow sorting, which can be very prohibitive on a moderate amount of data(~5 000 000 records)

This is a default behaviour of Django Admin selecting query

SELECT * FROM `book` ORDER BY `book`.`added_at` ASC, `book`.`book_id` DESC LIMIT 100

I want to achieve the following behaviour

 SELECT * FROM `book` ORDER BY `book`.`added_at` ASC LIMIT 100
like image 766
pmapcat Avatar asked Sep 27 '16 10:09

pmapcat


People also ask

How do I sort data in Django admin?

When you add a calculated field Django doesn't know how to do a order_by , so it doesn't add sorting capability on that field. If you want to add sorting on a calculated field, you have to tell Django what to pass to order_by . You can do this by setting the admin_order_field attribute on the calculated field method.

How do I set primary key in Django?

If you'd like to specify a custom primary key, specify primary_key=True on one of your fields. If Django sees you've explicitly set Field.primary_key , it won't add the automatic id column. Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).

How can I remove extra's from Django admin panel?

You can add another class called Meta in your model to specify plural display name. For example, if the model's name is Category , the admin displays Categorys , but by adding the Meta class, we can change it to Categories . Literally saved my life!

What is the default primary key in Django?

Primary Keys By default, Django adds an id field to each model, which is used as the primary key for that model. You can create your own primary key field by adding the keyword arg primary_key=True to a field. If you add your own primary key field, the automatic one will not be added.


1 Answers

I guess I'm a bit late in here, but this may help someone in the future.

Django enforces a -pk ordering in order to be sure resulting queryset is deterministic - see here and here for example.

If you really want to disable it you can create your own ChangeList subclass and override get_ordering method like:

from django.contrib import admin
from django.contrib.admin.views.main import ChangeList

class NoPkDescOrderedChangeList(ChangeList):
    def get_ordering(self, request, queryset):
        rv = super().get_ordering(request, queryset)
        rv = list(rv)
        rv.remove('-pk') if '-pk' in rv else None
        return tuple(rv)

class YourExistingAdmin(admin.ModelAdmin):
    def get_changelist(self, request):
        return NoPkDescOrderedChangeList
like image 156
waitman Avatar answered Oct 20 '22 17:10

waitman