Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Loading Many-To-Many relationship admin page is so slow

Tags:

django

admin

(Django 1.8) I have a table which has 4 many-to-many relationship to other tables. Two of these tables have so many entries and that is causing the admin page to load very slowly because it is trying to load all the entries in the lists. Is there a way to avoid the internal admin page query for loading all the entries of the big tables to speed up the admin page load? I think the best way is to only list the selected values but I'm not sure how.

I'm not sure how to use limit_choices_to in here:

class Data(models.Model):
    pass # stuff here

class Report(models.Model):
    data= models.ManyToManyField(Data)

I also tried adding this to my admin.py but it did not help at all. It's not limiting for some reason:

def queryset(self, request):
    qs = super(MyModelAdmin, self).queryset(request)
    if len(qs) > 10:
        qs = qs[:10]
    return qs
like image 809
max Avatar asked Jul 16 '15 15:07

max


People also ask

Is Django admin useful?

The Django admin application can use your models to automatically build a site area that you can use to create, view, update, and delete records. This can save you a lot of time during development, making it very easy to test your models and get a feel for whether you have the right data.

Can we customize Django admin panel?

The Django admin is a powerful built-in tool giving you the ability to create, update, and delete objects in your database using a web interface. You can customize the Django admin to do almost anything you want.


1 Answers

If you still want to use limit_choices_to, then please refer to the docs. You basically just supply the filters in a dictionary object.

To speed up the admin, my suggestions include:
1. Using raw_id_fields in your ModelAdmin. This gives you a little searchbox instead of a selectbox and avoids the overhead of listing all related objects.
2. If you are handling forward ForeignKey relationships, you can use list_select_related in your ModelAdmin as well. In your case, you are handling many-to-many relationships, so you can try overriding the get_queryset method of the ModelAdmin, and use prefetch_related like in the code below.

from django.contrib import admin

class TestModelAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        test_model_qs = super(TestModelAdmin, self).get_queryset(request)
        test_model_qs = test_model_qs.prefetch_related('many-to-many-field')
        return test_model_qs

If you really like to get your hands dirty, I highly recommend you use django-debug-toolbar. It really gives you visibility on how many and what SQL statements are being run. If you can read SQL, you can deduce what you need to input to select_related and prefetch_related.

like image 108
Wannabe Coder Avatar answered Oct 19 '22 12:10

Wannabe Coder