Shashi Mishra
Shashi Mishra

Reputation: 115

Trailing slash is not added when DEBUG is False in Django 1.9

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

Answers (2)

Akaisteph7
Akaisteph7

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

rychlis
rychlis

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

Related Questions