Append OR remove slash in Django
2013-12-07
A frustration of mine is that while django provides the very useful APPEND_SLASH setting, it doesn't have a complementary REMOVE_SLASH setting, for those who prefer non-slashed urls.
Further, there are legitimate reasons to have trailing slashes on some urls, but not on others, so I wrote this short middleware to deal with the situation. It works just like APPEND_SLASH, and also works in reverse — e.g. it will remove the slash if a slash-appended url won't resolve, but its non-slashed counterpart will.
Usage
Download the code below and add slash_middleware.AppendOrRemoveSlashMiddleware
to your MIDDLEWARE setting - somewhere near the start is best, usually right after CommonMiddleware. You also probably want to set APPEND_SLASH = False
, since it will be redundant.
Potential issues
If you have an included urlconf followed by a catch-all without a trailing slash, the slash-append will not work - this issue is inherent with django, but can be solved by using a trailing slash on all urls, which is why we have APPEND_SLASH but no REMOVE_SLASH. For example:
urlpatterns = [
url(r'^myurl/', include('myapp.urls')),
url(r'^([\w\-]+)$', views.myview),
]
A request to /myurl will be resolved by the second url and therefore not be caught by the middleware, which detects 404s at the url level but not those raised by a view. The result will generally be a 404 when a redirect to /myurl/ might be expected. To work around this an explicit redirect is required, e.g
urlpatterns = [
(r'^myurl$', RedirectView.as_view(url='/myurl/')),
url(r'^myurl/', include('myapp.urls')),
url(r'^([\w\-]+)$', views.myview),
]