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.
Example
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[1].endswith('/')) and not _resolves(old_url[1]) and _resolves(old_url[1] + '/'):
new_url[1] = new_url[1] + '/'
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[0], new_url[1])
if new_url != old_url:
# Redirect
if new_url[0]:
newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url[0], new_url[1])
else:
newurl = new_url[1]
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
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.