Queryset optimization in Admin

class ProductAdmin(admin.ModelAdmin):
    ...
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        qs = qs.select_related(
            'subcategory__category__main_category'
        ).prefetch_related(
            'product_images',
            'product_in_stock',
            Prefetch('product_specs', queryset=ProductSpec.objects.prefetch_related('product_spec_key'))
        )
        return qs

This approach works terrific in views, but on admin page I’ve got even more database hits (200+ compared to 190+).
Is it possible to optimize queryset in Admin in this way, perhaps with a bit more overriding of parent class?

1 Like

Jacinda Shelly gave a wonderful talk at PyCon last year titled, “But, Why is the admin slow?” - https://youtu.be/f8cFjiyxQuQ

If you’re really interested in improving the performance of your admin pages, it’s well worth your time to watch it.

She’s really talking about a more general issue regarding performance improvements, but it’s remarkably useful for optimizing the queries being performed in the ModelAdmin classes.

Ken

1 Like

Thank you Ken, I’ll check this one!

Looks like get_queryset has to do with LISTS of objects but doesn’t have any impact on INDIVIDUAL objects in admin…
I’ve got several Inlines and a ForeignKey selector with verbose __str__ as major culprits of slowdown.

One clue here: formfield_for_foreignkey

Also take a look at ModelAdmin.autocomplete_fields. That’ll be helpful if you can’t filter the choices.

Thanks, great hint!
The worst part is with inlines - they produce dozens of extra database queries, and the seem to be no way to reduce them to one query.