There are cases when rendering had already started, but you have to return Your response nevertheless. A good example is when you have a django-cms plugin and a form in it. You want to redirect after the form was processed, but normally you can't do it.
More information here: https://github.com/divio/django-cms/issues/79 http://groups.google.com/group/django-cms/browse_thread/thread/79ab6080c80bbcb5?pli=1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | """
Motivation
==========
There are cases when rendering had already started, but you have to return Your response nevertheless. A good example is when you have a django-cms plugin and a form in it. You want to redirect after the form was processed, but normally you can't do it.
More information here:
https://github.com/divio/django-cms/issues/79
http://groups.google.com/group/django-cms/browse_thread/thread/79ab6080c80bbcb5?pli=1
Usage
=====
1) Add ForceRedirectsMiddleware to MIDDLEWARE_CLASSES in your settings.py
2) throw ForceResponse(HttpResponseRedirect(reverse('your_view_name'))) whenever you want.
Code example (working cms plugin):
==================================
from cv.utils import ForceResponse
class CVPlugin(CMSPluginBase):
def render(self, context, instance, placeholder):
request = context['request']
if request.method == 'POST':
cv_form = CVForm(request.POST, request.FILES)
else:
cv_form = CVForm()
if not cv_form.is_valid():
context.update({ 'form' : cv_form })
return context
# Saving CV
cv = cv_form.save(commit=False)
code = cv.gen_code()
cv.save()
raise ForceResponse(HttpResponseRedirect(reverse('dashboard',
kwargs={'code': cv.code})))
plugin_pool.register_plugin(CVPlugin)
"""
class ForceResponse(Exception):
def __init__(self, response):
self.response = response
class ForceResponseMiddleware:
def process_exception(self, request, e):
"""Because django plugins cannot throw raw response
(redirect is required to user dashboard after form is submitted),
a solution is to raise an exception, catch it with middleware and
react.
This middleware checks for ForceResponse exception and returns it's
response object.
In reality, ForceResponse is caught as TemplateSyntaxtError in cms
plugin. So we have to extract ForceResponse from it.
Instance of TemplateSyntaxError has exc_info field where it has the
original exception. exc_info[1] is the exception instance.
"""
from django.template import TemplateSyntaxError
if isinstance(e, TemplateSyntaxError) and getattr(e, 'exc_info', 0):
try:
e = e.exc_info[1]
except: # Not iterable or IndexError
raise e # as if nothing had happened
if isinstance(e, ForceResponse):
return e.response
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 9 months, 3 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months ago
- Serializer factory with Django Rest Framework by julio 1 year, 4 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 5 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
This is exactly what I needed for my django-cms form plugin :) Thanks!
#
Please login first before commenting.