Queryset.union() etc. vs. prefetch_related()

Hello all,

The queryset union() docs say:

only LIMIT , OFFSET , COUNT(*) , ORDER BY , and specifying columns (i.e. slicing, count() , exists() , order_by() , and values() / values_list() ) are allowed on the resulting QuerySet .

This makes sense, and is mostly caused by limitations imposed by SQL implementations – there’s not a lot of modifications you can add on such queries.

prefetch_related() is different – it adds separate queries, so SQL limitations do not really apply. The ORM still enforces it, though: If you call prefetch_related() on a union query, you get the standard exception:

django.db.utils.NotSupportedError: Calling QuerySet.prefetch_related() after union() is not supported.

Somewhat surprisingly, if you call prefetch_related() before union(), it is applied (on the union queryset) – hinting that there is no good reason for the restriction.

Does anybody know a reason why we shouldn’t support prefetch_related() after union()?

(prefetch_related() on the argument querysets is silently ignored, that is, in qs1.union(qs2), if qs1 has prefetch_related() called on it, it is applied, but a prefetch_related() on qs2 is ignored)

4 Likes

Not really. We have an accepted ticket #28519 for supporting other QuerySet methods on combined QuerySets, so a patch is welcome :gift: .

1 Like