Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django admin edit model select/prefetch_related?

I have a Django website, with model Event, lets say:

class Event(models.Model):
    home = models.ForeignKey('Team', related_name='%(class)s_home')
    away = models.ForeignKey('Team', related_name='%(class)s_away')
    ...

class Team(models.Model):
    name = models.CharField("team's name", max_length=100)

Using ForeignKeys for this was a bad idea, but anyway, how to make this usable in Django Admin page?
In admin edit event page, a ton of foreign keys is fetched for this:
http://127.0.0.1:8000/admin/event/event/116255/

It produces tons of selects like:
SELECT "event_team"."id", "event_team"."name" FROM "event_team" WHERE "event_team"."id" = 346;

and page dies. I was playing with these:

class EventAdmin(admin.ModelAdmin):
    list_display = ('id', 'home', 'away', 'date_game', 'sport', 'result')
    search_fields = ['home__name', 'away__name']
    list_select_related = (
        'home', 'away', 'league', 'sport', ...
    )

    def get_queryset(self, request):
        return super(EventAdmin, self).get_queryset(request).select_related(*self.list_select_related)
admin.site.register(Event, EventAdmin)

But no luck.

like image 713
Lucas03 Avatar asked Oct 29 '22 00:10

Lucas03


2 Answers

The simplest, quickest way

It would be to add raw_id_fields on your ModelAdmin (Django ModelAdmin.raw_id_fields documentation) :

class EventAdmin(admin.ModelAdmin):
    raw_id_fields = ("home", "away")

It would result in a inputText with the FK field ids in such as : Django ModelAdmin.raw_id_fields text Input example.
Loading will be fast as it won't populate a select list with ALL the teams.
You'll have the Django admin change_view of the Team ModelAdmin to select the teams, thanks to the browse icon.

A nicer way ?

A lot more elegant on the UX side of things, it requires you to know part of the name of the team: using an ajax autocomplete widget to represent your field.

You could use for example Django Autocomplete Light (DAL) quick tutorial by having a custom form for your admin and a autocompleteModelSelect2 for your home and away fields (with 2 differents QS in the ajax view).
It will produce a field looking like:

DAL autocomplete ModelSelect2 widget example.
The tutorial of this link have all you need!

Or you can chose another third party plugin or build your own field/widget to produce a similar result.

like image 90
ppython Avatar answered Nov 09 '22 07:11

ppython


I think @ppython's answer is the simplest and works perfectly but I ended up using autocomplete_fields instead of raw_id_fields. Achieving a more friendly approach, it has been available since Django 2.0.

Following the answer, it'll be something like this:

class EventAdmin(admin.ModelAdmin):
    autocomplete_fields = ['home', 'away']
like image 37
David Lilue Avatar answered Nov 09 '22 06:11

David Lilue