Hi all, Ticket #15012 highlights that you can't use a cache_page decorators on pages that return a TemplateResponse. The problem goes like this:
* A decorator operates on the output of a function * cache_page stores the output of a function so it can be used in the future instead of invoking the function again * The output of a function returning a TemplateResponse hasn't been fully computed, and (at least at present) isn't pickleable * So a TemplateResponse can't be cached. This was noted as a problem during the discussion of the render() shortcut, but #15012 points out a bigger implication -- the TemplateView generic view uses TemplateResponse. Which means you can't cache the output of a simple template generic view. This is a fairly big oversight, which is why #15012 is on the blocker list. There are at least 4 fixes to this problem that I can see. 1) Revert the TemplateView to use old-style static responses, rather than TemplateResponse. You would still be able to get a TemplateResponse with a simple configuration change (specifying TemplateResponse instead of shortcuts.render as the response_class). This seems like a case of not eating our own dogfood, but it's the easiest fix. 2) Fix TemplateResponse to make it pickleable. This would work, but does somewhat defeat the purpose of caching -- to save CPU cycles by storing fully rendered page output. What would be pickled is a template and a context that would need to be re-evaluated. 3) Modify cache_page to raise an error if it is used on a TemplateResponse. This doesn't fix the problem; it just makes sure you know why the problem exists. 4) Modify cache_page to force a render of the response. This defeats the purpose of introducing TemplateResponse, and would mean that template response middleware would be executed, but ignored. 5) Modify cache_page so that you can decorate a function with cache_page, but have the caching take effect later in the response cycle (i.e., after TemplateResponse has been actually rendered). I feel like 5 would be the the most desirable outcome, but I have no idea how it could even be implemented. The only thought I've had is that maybe the decorator could annotate the response with a callback that is invoked once the rendering process has been completed. However, this would be prone to ordering problems -- for example, consider the following stack: @other_dec @cache_page def my_view(request): ... At present, if other_dec is page modifying, those modifications will not be cached; if the effect of cache_page are deferred, they will be. So - opinions? Have I missed any options? Any other ideas on how to achieve (5)? Yours, Russ Magee %-) -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.
