Login

RegEx redirect fallback middleware

Author:
bowdengm
Posted:
July 8, 2012
Language:
Python
Version:
1.4
Score:
0 (after 0 ratings)

Simple middleware to complement the built in redirect middleware app. Add this after the contrib.redirect middleware - this will be fired if a 404 is triggered and the contrib.redirect fails to find a suitable redirect.

Useful if you want to add the redirects into the DB - and/or don't have access to the .htaccess script or whatever HTTP server based redirect machinery your site runs off.

You simply add in regex 'old_path' and 'new_path' entries into the same redirect app, but this will try to do a regex find and replace - i.e.

r = new Redirect() r.old_path = '/my/test/path/([a-z]+)/with/regex/' r.new_path = '/my/result/path/$1/with/regex/' r.save()

this will convert:

/my/test/path/abcdef/with/regex/

into:

/my/result/path/abcdef/with/regex/'

also works with query strings:

/index.php?section=products

old_path = '/index.php/\?section=([a-z]+)'

need to add in the forward slash if ADD_SLASHES = True in your settings, and escape the question mark.

new_path = '/section/$1/'

converts the url to '/section/products/'

 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
from django.contrib.redirects.models import Redirect
from django import http
from django.conf import settings
import re

class RegExRedirectFallbackMiddleware(object):
    def process_response(self, request, response):
        if response.status_code != 404:
            return response # No need to check for a redirect for non-404 responses.
        path = request.get_full_path()
        
        
        redirects = Redirect.objects.filter(site__id__exact=settings.SITE_ID)
        for r in redirects:
            try:
                old_path = re.compile(r.old_path, re.IGNORECASE)
            except re.error:
                # old_path does not compile into regex, ignore it and move on to the next one
                continue
                
            if re.match(r.old_path, path):
                new_path = r.new_path.replace('$', '\\')
                replaced_path = re.sub(old_path, new_path, path)
                return http.HttpResponsePermanentRedirect(replaced_path)
            
        # Return the response.
        return response

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

Please login first before commenting.