Cerin
Cerin

Reputation: 64689

Improving Performance of Django ForeignKey Fields in Admin

By default, Django's admin renders ForeignKey fields in admin as a select field, listing every record in the foreign table as an option. In one admin-accessible model, I'm referencing the User model as a ForeignKey, and since I have thousands of users Django is populating the select with thousands of options. This is causing the admin page to load incredibly slowly, and the select is not very useful since it can take a while to scroll through thousands of options to find the one you want.

What's the best way to change the rendering of this field in order to improve page load and usability? I'd like the select field to be replaced with some sort of button to launch a search form popup, or a text field that searches keywords via Ajax to find the Id for the specific User they want to associate. Does admin have anything like this builtin, or would I have to write this from scratch?

Upvotes: 20

Views: 8603

Answers (5)

teja duluri
teja duluri

Reputation: 21

class CustomAdmin(models.ModelAdmin):
    autocomplete_fields = ['foreignkey_field']

Upvotes: 1

Flimm
Flimm

Reputation: 150483

You're right, Cerin, the cause of the slowdown is because Django is populating the <select> element with too many options. You might want to use an autocomplete element instead.

Interestingly, Django 2.0 has introduced a new feature on the admin site, called autocomplete_fields, which I think you will find useful in this case. It uses AJAX.

class ExampleAdmin(models.ModelAdmin):
    autocomplete_fields = ['example_field_user']

Upvotes: 15

Kritz
Kritz

Reputation: 7301

Another option is to add readonly_fields instead of raw_id_fields

Upvotes: 0

Etienne
Etienne

Reputation: 12580

You can use one of the few autocomplete apps for Django. Check them at Django Packages.

There's also django-extensions that have ForeignKeyAutocompleteAdmin that fit your needs pretty well.

Upvotes: 11

Daniel Roseman
Daniel Roseman

Reputation: 599450

Add raw_id_fields to your model to only show the ID instead of a dropdown.

Upvotes: 30

Related Questions