This middleware replaces the behavior of the APPEND_SLASH setting in the CommonMiddleware. Please set
APPEND_SLASH = False and
SMART_APPEND_SLASH = True if you are going to use this middleware.
In your URL patterns, omit the trailing slash for URLs you want accessible without the slash. Include the slash for those URLs you wish to be automatically redirected from an URL with the slash missing.
If a URL pattern exists both with and without a slash, they are treated as two distinct URLs and no redirection is done.
urlpatterns = patterns('some_site.some_app.views', (r'^test/no_append$','test_no_append'), (r'^test/append/$','test_append'), (r'^test/distinct_url$', 'view_one'), (r'^test/distinct_url/$', 'view_two'), )
Behavior of URLs against the above patterns with SMART_APPEND_SLASH enabled:
http://some_site/test/no_append → test_no_append() http://some_site/test/no_append/ → 404 http://some_site/test/append → http://some_site/test/append/ http://some_site/test/append/ → test_append() http://some_site/test/distinct_url → view_one() http://some_site/test/distinct_url/ → view_two()
This module is also available in our SVN repository.
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
from django.conf import settings from django import http from django.core.urlresolvers import resolve class SmartAppendSlashMiddleware(object): """ "SmartAppendSlash" middleware for taking care of URL rewriting. This middleware appends a missing slash, if: * the SMART_APPEND_SLASH setting is True * the URL without the slash does not exist * the URL with an appended slash does exist. Otherwise it won't touch the URL. """ def process_request(self, request): """ Rewrite the URL based on settings.SMART_APPEND_SLASH """ # Check for a redirect based on settings.SMART_APPEND_SLASH host = http.get_host(request) old_url = [host, request.path] new_url = old_url[:] # Append a slash if SMART_APPEND_SLASH is set and the resulting URL # resolves. if settings.SMART_APPEND_SLASH and (not old_url.endswith('/')) and not _resolves(old_url) and _resolves(old_url + '/'): new_url = new_url + '/' if settings.DEBUG and request.method == 'POST': raise RuntimeError, "You called this URL via POST, but the URL doesn't end in a slash and you have SMART_APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to %s%s (note the trailing slash), or set SMART_APPEND_SLASH=False in your Django settings." % (new_url, new_url) if new_url != old_url: # Redirect if new_url: newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url, new_url) else: newurl = new_url if request.GET: newurl += '?' + request.GET.urlencode() return http.HttpResponsePermanentRedirect(newurl) return None def _resolves(url): try: resolve(url) return True except http.Http404: return False
More like this
- Serializer factory with Django Rest Framework by julio 5 months, 2 weeks ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 6 months, 1 week ago
- Help text hyperlinks by sa2812 7 months ago
- Stuff by NixonDash 9 months, 1 week ago
- Add custom fields to the built-in Group model by jmoppel 11 months, 1 week ago