1
votes

When I load an inexistent url the page 404 does not show instead the page 500 is shown. Below my setups. Could you please guide me to turn Django on to show 404 page? Thanks

Ubuntu Server 16.04 ; Python 3.5.2 ; Django 2.0

cat contatoproj/urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from django.conf.urls import include
from django.conf.urls import handler404, handler500
from contatoapp import views
from contatoapp import views as myapp_views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', views.index, name='index'),
    url(r'^contato', views.contato, name='contato'),
]

handler404 = myapp_views.error_404
handler500 = myapp_views.error_500

cat contatoapp/views.py

from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext
from django.contrib import messages
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.conf import settings
from contatoapp.forms import ContatoForm

def error_404(request):
    data = {}
    return render(request, 'ops404.html', data)

def error_500(request):
    data = {}
    return render(request, 'ops500.html', data)

$ ls -la templates/ops*

-rwxr-xr-x 1 admweb admweb 614 Dec 13 15:31 templates/ops404.html
-rwxr-xr-x 1 admweb admweb 614 Dec 13 15:29 templates/ops500.html

cat contatoproj/settings.py

DEBUG = False
ALLOWED_HOSTS = ['*']
2

2 Answers

4
votes

If you're getting a 500 error for missing pages then it's because there is an error happening when Django tries to handle that response.

From looking at your code, this is probably because your 404 error handler is wrongly defined - it needs to accept a second exception argument which is missing. Change it to:

def error_404(request, exception):
    data = {}
    return render(request, 'ops404.html', data)

Also note that you should be returning a HttpResponseNotFound, otherwise the client will not receive a HTTP 404 response.

2
votes

You're getting an error in the process of handling the 404. This means you're getting a 500 instead.

As you're not doing anything special in your 500 or 404 views, you don't need to explicitly define the handler views for them using handler404/500.

Instead, you should define 404.html and 500.html in your templates directory. Django will use these instead of the default templates, and you don't need to re-implement the 404 and 500 views correctly.