different querysets for display and filters?

Hi!

I have an admin for a model that has many items in list_display, including foreign key relationships and counts. I also have a couple of fields in list_filter.

I noticed that to display the list it made tons of queries, so I decided to optimize this by overriding get_queryset and adding select_related and prefetch_related. I managed to reduce hundreds of small queries into a single big query.

This is great for the 100 displayed models. However, it adds a ton of overhead for list_filter fields! list_filter works by going through all the objects in the table and collecting the different values. Since it is using the same queryset as the display, it is bringing all those relationships, doing all those joins, which are not really needed. So I realized that my great optimization makes for a worse performance :frowning:

I searched the documentation to see if there is a different queryset for display and filter, but I haven’t found anything. Am I stumbling on a problem that has been solved or is there some room to improve here?

Would list_selected_related help avoid changing the queryset itself? The Django admin site | Django documentation | Django

Yes this is helpful! Obviously not as expressive as having a custom queryset but it is something.

Is there a way to follow foreign key relationships? I used to do this with prefetch_related.

You can follow foreign key relationships with select_related QuerySet API reference | Django documentation | Django

Obviously it could result in slow queries depending on the size of your tables etc.

I mean, reverse foreign key… one to many relationships.
As if my model is Book and I want to show the count of Page objects.

Have you explored using only() or defer() methods in your queryset to limit the fields fetched for list_filter while still optimizing the main display?

Have you explored using only() or defer() methods in your queryset to limit the fields fetched for list_filter while still optimizing the main display

No I haven’t tried it, it seems to me that the join will still happen but the fields won’t be retrieved?