I’m ordering a huge model, in its
ModelAdmin class, using an
ordering = ('-created',)
However, the generated query orders by both fields
ORDER BY "dl_revision"."created" DESC, "dl_revision"."id" DESC
This causes a huge problem with Postgres optimizer: for some reasons, it does not use foreign key indexes to perform joins (
Revision has two foreign key fields), but it makes a full table scan. If I manually remove ordering by
id from the query, the optimizer is able to perform joins using indexes.
As a (inefficient) workaround, I created a further combined index with fields
('created', 'id'), and the joins use indexes now.
My question is: is it possible to disable adding the
id column to the
order by clause, and stick with the fields explicitly requested only?
That’s the exact behaviour that Django’s documentation describes (https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.ordering), and your workaround is kind of suggested there as well.
Have you tried overriding the
get_ordering method? I haven’t tried, but by reading the docs and the code, it looks like you can achieve the expected outcome by doing that:
Thanks for all your info, now it is much clearer to me what happens behind the scene!
I’ve tried to override
get_ordering of class
def get_ordering(self, request):
but the situation does not change:
id is added to sorting fields by that
_get_deterministic_ordering_() function that is called by the framework after the call to the overridden
It looks like I should redefine the
_get_deterministic_ordering() method of class
ChangeView… more precisely, I should define a new class, say
RevisionChangeView that extends
ChangeView, override its methods, and in some way tell
RevisionAdmin to use
RevisionChangeView. But I don’t know if it is possible…