Django erstellt eine benutzerdefinierte 500/404-Fehlerseite


105

Nach dem tutorial hier genau, kann ich nicht eine benutzerdefinierte 500 oder 404 Fehlerseite erstellen. Wenn ich eine falsche URL eingebe, gibt mir die Seite die Standardfehlerseite. Gibt es etwas, auf das ich prüfen sollte, um zu verhindern, dass eine benutzerdefinierte Seite angezeigt wird?

Dateiverzeichnisse:

mysite/
    mysite/
        __init__.py
        __init__.pyc
        settings.py
        settings.pyc
        urls.py
        urls.pyc
        wsgi.py
        wsgi.pyc
    polls/
        templates/
            admin/
                base_site.html
            404.html
            500.html
            polls/
                detail.html
                index.html
        __init__.py
        __init__.pyc
        admin.py
        admin.pyc
        models.py
        models.pyc
        tests.py
        urls.py
        urls.pyc
        view.py
        views.pyc
    templates/
    manage.py

In mysite / settings.py habe ich Folgendes aktiviert:

DEBUG = False
TEMPLATE_DEBUG = DEBUG

#....

TEMPLATE_DIRS = (
    'C:/Users/Me/Django/mysite/templates', 
)

innerhalb von mysite / polls / urls.py:

from django.conf.urls import patterns, url

from polls import views

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
    url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
    url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)

Ich kann jeden anderen erforderlichen Code veröffentlichen, aber was sollte ich ändern, um eine benutzerdefinierte 500-Fehlerseite zu erhalten, wenn ich eine schlechte URL verwende?

Bearbeiten

LÖSUNG: Ich hatte eine zusätzliche

TEMPLATE_DIRS

innerhalb meiner settings.py und das verursachte das Problem


1
Debug ist in meinem Code auf False gesetzt
Zac

Dies könnte Ihnen helfen stackoverflow.com/a/12180499/1628832
karthikr

1
Ich habe diese Antwort gefunden, als ich nach einer Möglichkeit gesucht habe, nur eine benutzerdefinierte Vorlage zu erstellen, und wollte ein bisschen Django-Dokumentation teilen, was mir sehr geholfen hat. docs.djangoproject.com/de/1.7/ref/views/…
Blackeagle52

Meins funktionierte ohne die Einstellung template_dirs.
Programmingjoe

1
Punkte für Ironie, wenn der Link in der ersten Zeile zu Djangos 404-Seite führt. Führt zu einer Tutorial-Seite für eine Version von Django, die es meiner Meinung nach nicht gibt. Hier ist der Link zur Tutorial-Seite für Django 2.0: docs.djangoproject.com/de/2.0/intro/tutorial03
andrewec

Antworten:


120

Fügen Sie unter Ihrem Hauptbild views.pyIhre eigene benutzerdefinierte Implementierung der folgenden beiden Ansichten hinzu und richten Sie einfach die Vorlagen 404.html und 500.html mit den gewünschten Informationen ein .

Mit dieser Lösung muss kein benutzerdefinierter Code hinzugefügt werden urls.py

Hier ist der Code:

from django.shortcuts import render_to_response
from django.template import RequestContext


def handler404(request, *args, **argv):
    response = render_to_response('404.html', {},
                                  context_instance=RequestContext(request))
    response.status_code = 404
    return response


def handler500(request, *args, **argv):
    response = render_to_response('500.html', {},
                                  context_instance=RequestContext(request))
    response.status_code = 500
    return response

Aktualisieren

handler404und handler500werden exportiert Django String Konfigurationsvariablen gefunden in django/conf/urls/__init__.py. Deshalb funktioniert die obige Konfiguration.

Damit die obige Konfiguration funktioniert, sollten Sie die folgenden Variablen in Ihrer urls.pyDatei definieren und die exportierten Django-Variablen auf den Python-Zeichenfolgenpfad verweisen, in dem diese Django-Funktionsansichten definiert sind:

# project/urls.py

handler404 = 'my_app.views.handler404'
handler500 = 'my_app.views.handler500'

Update für Django 2.0

Die Signaturen für Handleransichten wurden in Django 2.0 geändert: https://docs.djangoproject.com/de/2.0/ref/views/#error-views

Wenn Sie Ansichten wie oben verwenden, schlägt handler404 mit der folgenden Meldung fehl:

"handler404 () hat ein unerwartetes Schlüsselwortargument 'Ausnahme' erhalten"

Ändern Sie in diesem Fall Ihre Ansichten wie folgt:

def handler404(request, exception, template_name="404.html"):
    response = render_to_response(template_name)
    response.status_code = 404
    return response

Dies schien für mich ganz gut zu funktionieren, aber aus irgendeinem Grund erscheint request.user in der 404-Vorlage in Ordnung, aber in der 500-Vorlage überhaupt nicht (und sie sind fast identisch) - hier gepostete Frage: stackoverflow.com/ Fragen / 26043211 /…
Gravity Grave

1
Eine andere Sache, über die ich mich gewundert habe - was ist, wenn Sie das Admin-Backend verwenden und separate Vorlagen für diese verwenden möchten? Meines Wissens hat der Administrator keine views.py, um diesen Code zu überschreiben und einzufügen.
Gravity Grave

11
@GravityGrave 500 templatewird nicht gerendert , request.userda ein 500-Server-Fehler gemeldet wird, sodass der Server nichts bereitstellen kann.
Aaron Lelevier

5
Hat bei mir mit django 1.9 nicht funktioniert; (Vielleicht mache ich etwas falsch. Ist handler404 django reservierter Name? Wie würde django wissen, dass es genau diese Ansicht aufrufen sollte?
deathangel908

1
Ich habe die Antwort basierend auf Ihrem Kommentar aktualisiert. Entschuldigung, dass das Update so spät ist. Ich hoffe das hilft.
Aaron Lelevier

71

Offizielle Antwort:

Hier ist der Link zur offiziellen Dokumentation zum Einrichten benutzerdefinierter Fehleransichten:

https://docs.djangoproject.com/de/stable/topics/http/views/#customizing-error-views

Es heißt, Zeilen wie diese in Ihre URLconf einzufügen (das Festlegen an einer anderen Stelle hat keine Auswirkung):

handler404 = 'mysite.views.my_custom_page_not_found_view'
handler500 = 'mysite.views.my_custom_error_view'
handler403 = 'mysite.views.my_custom_permission_denied_view'
handler400 = 'mysite.views.my_custom_bad_request_view'

Sie können die CSRF-Fehleransicht auch anpassen, indem Sie die Einstellung ändern CSRF_FAILURE_VIEW.

Standardfehlerbehandlungsroutinen:

Es lohnt sich, die Dokumentation der Standardfehlerbehandlungsroutinen zu lesen, page_not_found, server_error, permission_deniedund bad_request. Standardmäßig sie diese Vorlagen verwenden , wenn sie sie finden können, jeweils: 404.html, 500.html, 403.html, und 400.html.

Wenn Sie also nur hübsche Fehlerseiten erstellen möchten, erstellen Sie diese Dateien einfach in einem TEMPLATE_DIRS Verzeichnis. Sie müssen URLConf überhaupt nicht bearbeiten. Lesen Sie die Dokumentation, um festzustellen, welche Kontextvariablen verfügbar sind.

In Django 1.10 und höher verwendet die Standard-CSRF-Fehleransicht die Vorlage 403_csrf.html.

Erwischt:

Vergessen Sie nicht, dass DEBUGdies auf False gesetzt sein muss, damit diese funktionieren. Andernfalls werden die normalen Debug-Handler verwendet.


1
Ich habe hinzugefügt, aber es funktioniert nicht. Der Handler404 und andere, die auf die richtigen Stellen in meinen Ansichten verweisen, wurden hinzugefügt, aber es funktioniert nicht, da immer noch der Standard 404 angezeigt wird. Und ja, ich bin im Debug-Falsch-Modus und verwende 1.9
KhoPhi

Wenn Sie Django 1.9 verwenden und einfach 500.html usw.-Vorlagen hinzufügen, werden diese anstelle von Standardseiten angezeigt. Schöne einfache Lösung.
Curtisp

2
Gotcha hat mir geholfen. Es hat funktioniert, indem diese Änderungen in meiner settings.py vorgenommen wurden, DEBUG = False und ALLOWED_HOSTS = ['0.0.0.0'] gesetzt wurden, um http-Anfragen von jedem Client zu akzeptieren.
Shaffooo

1
Nur für den Fall, dass sich jemand fragt, wo auf der Erde URLconf ist, hier ist es
Arthur Tarasov

38

Fügen Sie diese Zeilen in urls.py hinzu

urls.py

from django.conf.urls import (
handler400, handler403, handler404, handler500
)

handler400 = 'my_app.views.bad_request'
handler403 = 'my_app.views.permission_denied'
handler404 = 'my_app.views.page_not_found'
handler500 = 'my_app.views.server_error'

# ...

und implementieren Sie unsere benutzerdefinierten Ansichten in views.py.

views.py

from django.shortcuts import (
render_to_response
)
from django.template import RequestContext

# HTTP Error 400
def bad_request(request):
    response = render_to_response(
        '400.html',
        context_instance=RequestContext(request)
        )

        response.status_code = 400

        return response

# ...

5
Warum sollten Sie handler400nur importieren , um es zu überschreiben handler400 = 'myapp.views.bad_request'?
Flimm


5
Sie müssen die Handler hier nicht importieren, um sie zu überschreiben.
Funkotron

1
Sie sollten nicht verwenden render_to_response. Aus den Dokumenten: "Es wird nicht empfohlen und wird wahrscheinlich in Zukunft veraltet sein."
Timmy O'Mahony

Für Django 1.10, wie render_to_responsees veraltet sein wird, siehe folgendes ( renderstattdessen verwenden): stackoverflow.com/questions/44228397/…
mrdaliri

21

Von der Seite, auf die Sie verwiesen haben:

Wenn Sie Http404 aus einer Ansicht heraus anheben, lädt Django eine spezielle Ansicht, die sich mit der Behandlung von 404-Fehlern befasst. Es wird gefunden, indem in Ihrer Root-URLconf nach der Variablen handler404 gesucht wird (und nur in Ihrer Root-URLconf; das Festlegen von handler404 an einer anderen Stelle hat keine Auswirkung). Dies ist eine Zeichenfolge in Python-Punktsyntax - das gleiche Format, das die normalen URLconf-Rückrufe verwenden. Eine 404-Ansicht selbst hat nichts Besonderes: Es ist nur eine normale Ansicht.

Ich glaube, Sie müssen Ihrer urls.py so etwas hinzufügen:

handler404 = 'views.my_404_view'

und ähnlich für handler500.


Wie sieht das aus, Mike? Heute ist mein erster Tag mit Django und ich hänge immer noch an den Seilen
Zac

2
@JimRilye Sie müssen Ihren Ansichten eine geeignete 500-Funktion hinzufügen und diese dann mit dieser Variablen referenzieren. Fügen Sie also über Ihrer urlpatterns = ...Zeile eine Zeile mit der Aufschrift handler500 = 'views.handle500'und dann eine def handle500(request):zu Ihrer views.py hinzu, die Ihre 500.html anzeigt.
Mike Pelley

18

Wenn Sie nur benutzerdefinierte Seiten DEBUG = Falseanzeigen möchten, die einige ausgefallene Fehlermeldungen für Ihre Site enthalten , fügen Sie zwei Vorlagen mit den Namen 404.html und 500.html in Ihr Vorlagenverzeichnis ein, und diese benutzerdefinierten Seiten werden bei 404 oder 500 automatisch abgerufen wird angehoben.


1
Dies funktioniert nur, stellen Sie sicher, dass Sie etwas haben wie: 'DIRS': [os.path.join(BASE_DIR, '<project_name>/templates')]in Ihrer TEMPLATES-Liste in settings.py.
Eric

12

In Django 2. * können Sie diese Konstruktion in views.py verwenden

def handler404(request, exception):
    return render(request, 'errors/404.html', locals())

In settings.py

DEBUG = False

if DEBUG is False:
    ALLOWED_HOSTS = [
        '127.0.0.1:8000',
        '*',
    ]

if DEBUG is True:
    ALLOWED_HOSTS = []

In urls.py

# https://docs.djangoproject.com/en/2.0/topics/http/views/#customizing-error-views
handler404 = 'YOUR_APP_NAME.views.handler404'

Normalerweise erstelle ich default_app und behandle Site-weite Fehler, Kontextprozessoren darin.


Arbeite für mich. Aber was ist das exception?
Zeleven

Laut Dokumentationslink: docs.djangoproject.com/de/2.1/ref/urls/… . Es steht geschrieben:
Stellen

1
Arbeitete für mich in Django 3.0 . Aber was ist das locals()? Die Datei wird nur angezeigt pass.
Enchance

9

settings.py:

DEBUG = False
TEMPLATE_DEBUG = DEBUG
ALLOWED_HOSTS = ['localhost']  #provide your host name

und fügen Sie einfach Ihre 404.htmlund 500.htmlSeiten im Vorlagenordner hinzu. Entfernen 404.htmlund 500.htmlaus Vorlagen in der Umfrage-App.


Verwendung der Nachricht von raise Http404('msg'): stackoverflow.com/a/37109914/895245 {{ request_path }} ist ebenfalls verfügbar.
Ciro Santilli 法轮功 冠状 病 六四 事件 9


7

Machen Sie einen Fehler. Finden Sie auf der Fehlerseite heraus, wo Django Vorlagen lädt. Ich meine den Pfadstapel. Fügen Sie in base template_dir diese HTML-Seiten 500.html , 404.html hinzu . Wenn diese Fehler auftreten, werden die entsprechenden Vorlagendateien automatisch geladen.

Sie können auch Seiten für andere Fehlercodes wie 400 und 403 hinzufügen .

Ich hoffe das hilft !!!


6

In Django 3.xfunktioniert die akzeptierte Antwort nicht, da render_to_responsesie vollständig entfernt wurde und seit der Version, für die die akzeptierte Antwort funktioniert hat, weitere Änderungen vorgenommen wurden.

Es gibt auch einige andere Antworten, aber ich präsentiere eine etwas sauberere Antwort:

In Ihrer Hauptdatei urls.py:

handler404 = 'yourapp.views.handler404'
handler500 = 'yourapp.views.handler500'

In yourapp/views.pyDatei:

def handler404(request, exception):
    context = {}
    response = render(request, "pages/errors/404.html", context=context)
    response.status_code = 404
    return response


def handler500(request):
    context = {}
    response = render(request, "pages/errors/500.html", context=context)
    response.status_code = 500
    return response

Stellen Sie sicher, dass Sie render()in eine yourapp/views.pyDatei importiert haben :

from django.shortcuts import render

Randnotiz: render_to_response()war in Django veraltet 2.xund wurde in der Überprüfung vollständig entfernt 3.x.


5

Als eine einzelne Zeile (für 404 generische Seite):

from django.shortcuts import render_to_response
from django.template import RequestContext

return render_to_response('error/404.html', {'exception': ex},
                                      context_instance=RequestContext(request), status=404)

1
Und wo soll man es verwenden?
Sami

4
# views.py
def handler404(request, exception):
    context = RequestContext(request)
    err_code = 404
    response = render_to_response('404.html', {"code":err_code}, context)
    response.status_code = 404
    return response

# <project_folder>.urls.py
handler404 = 'todo.views.handler404' 

Dies funktioniert auf Django 2.0

Stellen Sie sicher, dass Sie Ihre benutzerdefinierten 404.htmlElemente in den Ordner mit den App-Vorlagen aufnehmen.


4

Django 3.0

Hier finden Sie einen Link zum Anpassen von Fehleransichten

Hier ist ein Link zum Rendern einer Ansicht

Geben Sie im urls.py(Haupt-, im Projektordner) Folgendes ein:

handler404 = 'my_app_name.views.custom_page_not_found_view'
handler500 = 'my_app_name.views.custom_error_view'
handler403 = 'my_app_name.views.custom_permission_denied_view'
handler400 = 'my_app_name.views.custom_bad_request_view'

und in dieser App ( my_app_name) setzen Sie in views.py:

def custom_page_not_found_view(request, exception):
    return render(request, "errors/404.html", {})

def custom_error_view(request, exception=None):
    return render(request, "errors/500.html", {})

def custom_permission_denied_view(request, exception=None):
    return render(request, "errors/403.html", {})

def custom_bad_request_view(request, exception=None):
    return render(request, "errors/400.html", {})

HINWEIS: Dies error/404.htmlist der Pfad, wenn Sie Ihre Dateien im Vorlagenordner des Projekts (nicht der Apps) ablegentemplates/errors/404.html ablegen. Platzieren Sie die Dateien daher an der gewünschten Stelle und schreiben Sie den richtigen Pfad.

HINWEIS 2: Wenn Sie nach dem erneuten Laden der Seite die alte Vorlage weiterhin sehen, ändern Sie sie settings.py DEBUG=True, speichern Sie sie und dann erneut zu False(um den Server neu zu starten und die neuen Dateien zu sammeln).


Zusätzlicher Hinweis: Wenn Sie in DEUB=FalseIhren statischen Dateien ausgeführt werden, werden diese möglicherweise nicht bereitgestellt, sodass Sie keine Vorschau Ihrer benutzerdefinierten Fehlervorlagenänderungen anzeigen können. Verwenden Sie ./manage.py runserver --insecurediese Option, um Django dazu zu bringen, ihnen trotzdem zu dienen.
Rob


3

Versuchen Sie, Ihre Fehlervorlagen nach zu verschieben .../Django/mysite/templates/?

Ich bin mir dessen sicher, aber ich denke, diese müssen für die Website "global" sein.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.