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.