Django admin very slow with many to many and several foreign key relationships

Hi,

I have the following three models in a many to many relationship:

class Division(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, editable=False)
    add_date = models.DateTimeField(auto_now_add=True)
    last_changed = models.DateTimeField(auto_now=True)
    dance_type = models.ForeignKey("DanceType", on_delete=models.PROTECT)
    age_group = models.ForeignKey("AgeGroup", on_delete=models.PROTECT, blank=True, null=True)
    skill_level = models.ForeignKey("SkillLevel", on_delete=models.PROTECT, blank=True, null=True)
    gender = models.ForeignKey("Gender", on_delete=models.PROTECT, blank=True, null=True)
    ordering = models.IntegerField(blank=True, null=True)
    active = models.BooleanField(default=True)


class Event(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, editable=False)
    add_date = models.DateTimeField(auto_now_add=True)
    last_changed = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=256)
    date = models.DateField()
    divisions = models.ManyToManyField(KernDivision, through="EventDivision", related_name="events")


class EventDivision(models.Model):
   division = models.ForeignKey(KernDivision, on_delete=models.CASCADE)
   event = models.ForeignKey(Event, on_delete=models.CASCADE)

The Division model has a bunch of Foreign Key relationships with simple Models like

class Gender(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
    add_date = models.DateTimeField(auto_now_add=True)
    last_changed = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=100)
    display_name = models.CharField(max_length=100)
    is_aktive = models.BooleanField(default=True)

or

class AgeGroup(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, editable=False)
    add_date = models.DateTimeField(auto_now_add=True)
    last_changed = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=100)
    short_description = models.CharField(max_length=50)
    description = models.CharField(max_length=100, blank=True)
    comment = models.CharField(max_length=100, blank=True)
    min_age = models.IntegerField(blank=True, null=True)
    max_age = models.IntegerField(blank=True, null=True)
    active = models.BooleanField(default=True)

In the Database there are the following number of entries for the different models:

DanceType: 6
AgeGroup: 15
SkillLevel: 8
Gender: 2
Divisions: 238
Events: 1

In the Admin I have:

admin.site.register(Gender)
admin.site.register(SkillLevel)
admin.site.register(AgeGroup)
admin.site.register(DanceType)
admin.site.register(Division)

class EventDivisionInline(admin.TabularInline):
    model = EventDivision
    extra = 1

@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
    inlines = [EventDivisionInline]

admin.site.register(EventDivision)

At the Admin page it takes over 15 seconds to open an Event and according to Djago Debug Toolbar it needs 1842 SQL Queries. That makes the Admin Site for the Event model practically unusable. Is there something I did wrong or what can I do to speed things up?

The hole project can be found at:
https://codeberg.org/mkleinschmidt/osv-backend

Thank you for your help.

Hello there!

You probably agree that’s a lot of queries, and most likely this is that’s causing the slow down.
In the SQL panel of the Django Debug Toolbar you can find which queries are being issued, and you probably will find a lot of similar or duplicated queries, they’re what you’re looking for to enhance the load time.
After you find which queries are repeating, them you can try to optimize them by using select_related or prefetch_related. This can be achieved by overriding the get_queryset method of your ModelAdmin child class, or the InlineModelAdmin child class.

You probably going to see a lot of repeated queries for the Division model, since it has a few ForeignKey fields.