CACHE_MIDDLEWARE_ANONYMOUS_ONLY and per-site cache conflict with lazy loading
|Reported by:||Alexis Bellido||Owned by:||nobody|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
When you enable per-site cache and use CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True on a Django 1.4 project you get cached views as an authenticated user if you don't access an object which bypasses lazy loading.
To reproduce, set per-site cache as indicated in the documentation and add CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True to settings.py. Then create a simple view and return a very simple response via render_to_response with static text.
I'm pretty sure there are performance reasons for this behavior and I understand that in most cases an authenticated user will be served a view returning one or more objects which will bypass lazy loading, hence getting non-cached pages, but in those few cases when no object is returned, it could be while developing with cache enabled, this violates the principle of least astonishment.
If you set CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True, you expect that authenticated users will never get cached pages.
To overcome this problem my first thought was writing this conditional cache decorator to check if a user is authenticated and then doing the same that never_cache does but then I thought this could be simplified just by assigning request.user to a variable in my view. That didn't work because request.user at this point is still a lazy loading object. My improved solution was calling request.user.is_authenticated() in the view and that results on a non cached page.
An alternative is accessing some method or attribute of the user object at the template level.
But in any case, I don't think these tricks should be needed if CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True would be respected.
Change History (3)
comment:1 Changed 4 years ago by
|Component:||Core (Cache system) → Documentation|
|Patch needs improvement:||unset|
|Triage Stage:||Unreviewed → Accepted|