Last active
October 30, 2018 09:46
-
-
Save wfehr/e19a1836168dc6ab1fd140fd02972899 to your computer and use it in GitHub Desktop.
Django middleware to remove trailing slashes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django import http | |
from django.conf import settings | |
from django.core import urlresolvers | |
from django.core.exceptions import ImproperlyConfigured | |
from django.utils.deprecation import MiddlewareMixin | |
class AppendOrRemoveSlashMiddleware(MiddlewareMixin): | |
""" | |
This middleware removes a given trailing slash if the resulting path is | |
valid. It doesn't change admin-URLs. | |
Inspiration: https://github.com/dghubble/django-unslashed/blob/master/ | |
unslashed/middleware.py | |
""" | |
def process_request(self, request): | |
new_url = old_url = request.path_info | |
if getattr(settings, 'APPEND_SLASH'): | |
raise ImproperlyConfigured("APPEND_SLASH may not both be True if " | |
"this middleware is used.") | |
# Remove trailing slash if the URL has one except for some url-parts | |
append_parts = ['/admin'] | |
append = False | |
for sp in append_parts: | |
if sp in old_url: | |
append = True | |
if append and not new_url.endswith('/'): | |
new_url += '/' | |
elif not append and new_url.endswith('/'): | |
new_url = new_url[:-1] | |
if new_url != old_url: | |
urlconf = getattr(request, 'urlconf', None) | |
if urlresolvers.is_valid_path(new_url, urlconf): | |
# keep given query-params | |
qs = request.META.get('QUERY_STRING', False) | |
if qs: | |
new_url += '?' + qs | |
if settings.DEBUG and request.method == 'POST': | |
raise RuntimeError( | |
("You called this URL via POST, but the URL ends in a " | |
"slash. Django can't redirect to the non-slash URL " | |
"while maintaining POST data. Change your form to " | |
"point to '%s' (without a trailing slash).") % | |
(new_url)) | |
return http.HttpResponsePermanentRedirect(new_url) | |
return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment