How to force Django Admin to use select_related?

Viewed 21925

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?

6 Answers

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.

For the admin edit/change a specific item page, foreign key select boxes may take a long time to load, to alter the way django queries the data for the foreign key:

Django docs on Using formfield_for_foreignkey

Say I have a field called foo on my Example model, and I wish to select ralated bar objects:

class ExampleAdmin(admin.ModelAdmin):

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
            if db_field.name == "foo":
                kwargs["queryset"] = Example.objects.select_related('bar')
            return super().formfield_for_foreignkey(db_field, request, **kwargs)

For the sake of completeness, I would like to add another option that was the most suitable for my use case.

As others have pointed out, the problem is often loading the data for select boxes. list_select_related does not help in this case.

In case you don't actually want to edit the foreign key field via admin, the easiest fix is making the respective field readonly:

class Foo(admin.ModelAdmin):
    readonly_fields = ('foreign_key_field1','foreign_key_field2',)

You can still display these fields, there will simply not be a select box, hence Django does not need to retrieve all the select box options from the database.

Related