One of my models is particularily complex. When I try to edit it in Django Admin it performs 1042 queries and takes over 9 seconds to process.
I know I can replace a few of the drop-downs with raw_id_fields
, but I think the bigger bottleneck is that it's not performing a select_related()
as it should.
Can I get the admin site to do this?
In Django 2.0+, a good way to improve performance of ForeignKey and ManyToMany relationships is to use autocomplete fields.
These fields don't show all related objects and therefore load with many fewer queries.
Although dr jimbob's answer makes sense, for my needs, I was able to simply override the get_queryset() method with a one-liner, even selecting a foreign key's foreign key. Maybe this could be helpful to someone.
you can try this
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_select_related
For my particular model, the particularly slow aspect is going through ForeignKeys when they were being displayed in forms, which aren't called using
select_related
, so that's the part I'm going to speed up.Looking through the relevant django source, you see in
django/contrib/admin/options.py
that the methodformfield_for_foreignkeys
takes each FKdb_field
and calls theForeignKey
class'sformfield
method, which is defined in django/db/models/fields/related/ like:From this, we see if we provide the
db_field
with akwargs['queryset']
we can define a custom queryset that will be use select_related (this can be provided byformfield_for_foreignkey
).So basically what we want to do is override
admin.ModelAdmin
withSelectRelatedModelAdmin
and then make our ModelAdmin subclasses ofSelectRelatedModelAdmin
instead ofadmin.ModelAdmin
This code sample doesn't cover admin
Inline
s orManyToManyField
s, or foreign_key traversal in functions called byreadonly_fields
or custom select_related queries, but a similar approach should work for those cases.