yunfeng.guo yunfeng.guo - 1 month ago 12
MySQL Question

Django, many duplicated queries in my TabularInline

This is the part of my models.py:

class Media(TimeStampedModel):
name = models.CharField(max_length=20)

class Topic(TimeStampedModel):
medias = models.ManyToManyField(Media, through='TopicAndMedia')

class TopicAndMedia(models.Model):
topic = models.ForeignKey(Topic)
media = models.ForeignKey(Media)
order = models.IntegerField(default=0)


This is the part of my admin.py:

class TopicAndMediaInline(admin.TabularInline):
model = TopicAndMedia

class TopicAdmin(admin.ModelAdmin):
inlines = (TopicAndMediaInline, )
...


When I visit the TOPIC admin site, it's too slow. Here is the snapshot of the django-debug-tool

enter image description here

There are many duplicated time-cost queries like select * from 'topics_media'. How can i solve this problem?

Answer

You are facing typical problem with django QuerySets. You got this queries because when you access related object which is not prefetched beforehand you make additional DB hit.

Read more https://docs.djangoproject.com/en/1.10/ref/models/querysets/#select-related and https://docs.djangoproject.com/en/1.10/ref/models/querysets/#prefetch-related

This should solve your problem

class TopicAdmin(admin.ModelAdmin):
    inlines = (TopicAndMediaInline,)

    def get_queryset(self, request):
        qs = super(TopicAdmin, self).get_queryset(request)
        qs = qs.prefetch_related('medias')
        return qs 
Comments