HttpMethodsMiddleware

 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
import re
import itertools

_HTML_TYPES = ('text/html', 'application/xhtml+xml')    

_SUPPORTED_TRANSFORMS = ['PUT', 'DELETE']

_FORM_RE = re.compile(r'((<form\W[^>]*\bmethod=(\'|"|))(%s)((\'|"|)\b[^>]*>))' % '|'.join(_SUPPORTED_TRANSFORMS), re.IGNORECASE)

_MIDDLEWARE_KEY = 'method_middleware_transform'
 
class HttpMethodsMiddleware(object):
    def process_request(self, request):
        if request.POST and request.POST.has_key(_MIDDLEWARE_KEY):
            if request.POST[_MIDDLEWARE_KEY].upper() in _SUPPORTED_TRANSFORMS:
                request.method = request.POST[_MIDDLEWARE_KEY]
        return None
           
    def process_response(self, request, response):
        if response['Content-Type'].split(';')[0] in _HTML_TYPES:
            # ensure we don't add the 'id' attribute twice (HTML validity)
            idattributes = itertools.chain(("id='" + _MIDDLEWARE_KEY + "'",), 
                                            itertools.repeat(''))
            def add_transform_field(match):
                """Returns the matched <form> tag with a modified method and
                the added <input> element"""
                return match.group(2) + "POST" + match.group(5) + \
                "<div style='display:none;'>" + \
                "<input type='hidden' " + idattributes.next() + \
                " name='" + _MIDDLEWARE_KEY + "' value='" + \
                match.group(4).upper() + "' /></div>"

            # Modify any POST forms
            response.content = _FORM_RE.sub(add_transform_field, response.content)
        return response

More like this

  1. RestfulView by whiteinge 5 years, 7 months ago
  2. caching parsed templates by forgems 5 years, 5 months ago
  3. Fieldsets for Views by Nad/ 3 years, 4 months ago
  4. A action decorator for URLs by Batiste 5 years, 1 month ago
  5. Using class methods as views by panyam 3 years, 11 months ago

Comments

peplin (on April 20, 2011):

Be aware that this snippet as is can expose your application to CSRF attacks. Django's CSRF checks will always occur after this middleware is run, and it currently only checks POST requests.

I've made some updates for our version of this snippet here (with more comments): https://github.com/bueda/django-comrade/commit/de4d38b0c503908f11d5d73a60e3beef4735997c

#

(Forgotten your password?)