Invalidate any existing prefetch cache on PUT requests. by tomchristie · Pull Request #4668 · encode/django-rest-framework (original) (raw)

The only drawback I can see to this approach is, if I remember well, in the absence of a prefetch cache, every use of the related objects from that point forward will trigger a query. (but double-check that, I did not follow the latest Django updates very closely).
Other than this, it seems to be better than the former approach in every aspect: faster, won't reload queryset that won't get used, will not raise a 404 if the update took the object out of the queryset.

I was wondering whether this could be a possible solution too, digging just a single bit deeper into the queryset internals:

cache = getattr(instance, '_prefetched_objects_cache', None) if cache: for key, queryset in cache.items(): cache[key] = queryset.all()

Or, invalidating the cache in place instead:

cache = getattr(instance, '_prefetched_objects_cache', None) if cache: for queryset in cache.values(): queryset._result_cache = None

The idea is using related objects will still use the prefetch cache. First use will re-load data from the database, subsequent loads will not.

(I for one would love to see a class-level flag allowing to disable that code section entirely, but if I am too isolated a user, I will just use my own altered UpdateMixin where I need it).