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.

Reply via email to