[Solved]-Debugging slow Django Admin views

9πŸ‘

As rantanplan commented, django debug toolbar is the easiest way to start profiling (shows all queries executed on page load, their EXPLAIN, their time taken to execute, etc). You could also have a look at a question regarding profiling a slow django installation here:
How to profile django application with respect to execution time?

That question mentions the use of hotshot, which is also referenced on Django’s Wiki under profiling django.

πŸ‘€Dan LaManna

5πŸ‘

I too have seen this with particular models in the Django Admin if their tables are very, very large (several million records will do the trick) and the table engine is MySQL’s InnoDB. It took me a while to figure out workarounds to get my Django admin humming again for tables with 100M+ records. The root problem ended up being expensive COUNT(*) queries on page load and also poorly constructed searching queries whenever I used one of my search_fields from the ModelAdmin.

I documented all my solutions here, so that they might one day help a fellow Django-er in distress: http://craiglabenz.me/2013/06/12/how-i-made-django-admin-scale/

πŸ‘€Craig Labenz

1πŸ‘

If you use Django with MySQL then there is a bug in MySQL with INNER JOINs optimization. If you try to use foreign keys in Admin.list_display Django will generate query with ordering and INNER JOINs which are extremely slow in MySQL.

There are two solutions to that:

  1. Use django-mysql-fix backend: https://pypi.python.org/pypi/django-mysql-fix

  2. Override get_query_set in AdminChangeList – remove select_related and set prefetch_related fields – more details are in my other answer here: https://stackoverflow.com/a/23097385/1178806

πŸ‘€Vlad Frolov

0πŸ‘

Here are some good answers regarding slow edit forms caused by ForeignKey tables with many records
Django admin change form load quite slow

Regarding List Views:
1) You can add list_per_page option and show less results:

class EventAdmin(admin.ModelAdmin):
    list_per_page = 20

2) Or use select_related():

2.1) For django < 1.6:

class EventAdmin(admin.ModelAdmin):
    def queryset(self, request):
        qs = super(EventAdmin, self).queryset(request)
        return qs.select_related('foreign_key_field1, foreign_key_field2, etc')

2.2) For django >= 1.6:

class EventAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super(EventAdmin, self).queryset(request)
        return qs.select_related('foreign_key_field1, foreign_key_field2, etc')

Of course, replace foreign_key_field1, and foreign_key_field2, etc with appropriate field names.

πŸ‘€Kostyantyn

Leave a comment