Reputation: 115
I have a Django 1.9 application, When the DEBUG
is true
. The application redirects to url with a trailing slash if it was not present. But I am getting a 404 error when the DEBUG
is False
. I tried adding setting APPEND_SLASH = True
, but nothing changed. My setup is nginx + gunicorn + Django 1.9.
Any insights are appreciated. Thank you.
Upvotes: 4
Views: 700
Reputation: 6524
My issue happened from upgrading Django 2.0 to 5.0. My custom 404 handling had been working perfectly fine before then, but somewhere in those updates, Django must have changed things internally.
I was explicilty redirecting things to my homepage if the exception was a 404. But as @rychlis mentioned, this code isn't run when DEBUG=True
(source). So, turning it off locally helped me replicate the issue. Then, I just had to make sure to check whether there was already a slash at the end of the URL causing issues and add it myself if not instead of redirecting.
from django.urls import resolve
from django.urls.exceptions import Resolver404
...
def error_404(request, exception):
"""
Send all 404 URL resolving errors to homepage.
"If DEBUG is set to True (in your settings module), then your 404 view will never be used, and your URLconf will be displayed instead, with some debug information."
Source: https://docs.djangoproject.com/en/5.0/ref/views/#the-404-page-not-found-view
"""
if type(exception) == Resolver404:
appended = f'{request.path}/'
try:
# Make sure the appended URL actually exists to avoid a double redirect when it doesn't
append_slash_found = request.path[-1] != '/' and resolve(appended)
except Resolver404:
append_slash_found = False
new_path = appended if append_slash_found else '/'
return shortcuts.redirect(new_path, permanent=append_slash_found)
else:
# Return the default Django 404 page at a minimum as a visual aid for devs
return HttpResponseNotFound('<h1>Not Found</h1><p>The requested resource was not found on this server.</p>')
Upvotes: 0
Reputation: 136
Slash appending was moved to response handler in Django 1.9 and is only applied if the response.status_code
is 404: https://github.com/django/django/blob/1.9.3/django/middleware/common.py#L113
I've encountered same issue issue and in my case this was caused by my custom 404 view that actually returned HTTP 200. Make sure your 404 view creates responses with 404 status_code.
The reason this behavior doesn't happen with DEBUG = True
is that custom 404 is not used when in DEBUG
mode.
Upvotes: 3