Hi all,

For your consideration, I present a patch to resolve #12815 and
#12816, adding a TemplateResponse and a render() shortcut.

Barring objection or feedback, my intention is to commit this patch mid week.

This patch adds two features.

Firstly, it adds a render() shortcut. This is just
render_to_response(), but defaulting to using a RequestContext.

Secondly, it adds a TemplateResponse class. This class is a 'lazy
rendered' response -- you give it a request, template and context, and
it defers rendering until late in the response process.

The original idea for this feature was proposed by Simon Willison. The
purpose is to allow decorators and middleware to modify a response
after the view has finished with it. For example, you may have a
middleware that modifies the template context, or changes the template
depending on request-specific conditions -- for example, moving to
using a different template if a mobile platform is detected.

To do this, a TemplateResponse defers the rendering of a template
until it is 'baked'. A TemplateResponse must be baked before
response.content can be accessed; it is the baking process that
combines the template and context into the final response content.
Once baked, a TemplateResponse cannot be rebaked -- but you can
manually set the response content. Attempts to access response.content
before it is baked will raise an exception.

This patch also introduces a new middleware layer -- the Template
Response middleware. This middleware layer is invoked once the view
has been invoked. When all template_response middlewares have been
invoked, the response is baked, and the response middlewares are
invoked.

This patch also modifies the generic TemplateReponseMixin to use the
new TemplateResponse class. This allows for the removal of several
methods on the TemplateResponseMixin, as their functions are subsumed
by the TemplateResponse itself. If you don't want to use a
TemplateResponse, you can provide your own factory for responses;
because render() has the same signature as the TemplateResponse
constructor, you can use the render shortcut as a substitute.

A big thanks to Mikhail Korobov and Ivan Sagalaev for their input in
the design process, and especially to Mikhail for producing the draft
patch.

For those that followed the discussions and the original draft
patches, some notable changes:

 - The render() shortcut doesn't use TemplateResponse. Since render()
and TemplateReponse() have exactly the same prototype, I didn't see
the value in adding a shortcut that just redirected to a different
constructor. However, there is still value in making an easy-to-use
render_to_response, for those situations where a TemplateResponse
can't be used.

 - I've disabled repeat baking. My motivation for this is the fact
that there is an automated baking step at the end of the template
response middleware, so the effects of any calls to bake will be
automatically overridden by Django's own stack. By disabling repeat
baking, we can ensure that if the user actually requests baking, that
baking sticks. Manual assignment of response.content can be used to
overcome this -- response.bake() won't rebake content, but
response.content = response.render() will force the new content to be
applied.

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 django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to