Django、カスタム500/404エラーページの作成


105

ここにあるチュートリアルに従って、500または404のカスタムエラーページを作成できません。不適切なURLを入力した場合、ページにはデフォルトのエラーページが表示されます。カスタムページが表示されないようにするために確認すべきことはありますか?

ファイルディレクトリ:

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

mysite / settings.py内で、これらを有効にします。

DEBUG = False
TEMPLATE_DEBUG = DEBUG

#....

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

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'),
)

必要な他のコードを投稿できますが、不正なURLを使用している場合、カスタム500エラーページを取得するために何を変更する必要がありますか?

編集する

解決策: 追加の

TEMPLATE_DIRS

私のsettings.py内で、それが問題の原因でした


1
私のコードでデバッグがFalseに設定されている
Zac


1
カスタムテンプレートのみを作成する方法を探しているときにこの答えが見つかりました。Djangoのドキュメントを少し共有したいと思いました。docs.djangoproject.com/en/1.7/ref/views/...
Blackeagle52

私はtemplate_dirs設定なしで動作しました。
Programmingjoe

1
1行目のリンクがDjangoの404ページにつながるときの皮肉なポイント。存在しないDjangoのバージョンのチュートリアルページに移動します。Django 2.0のチュートリアルページへのリンクは次のとおり
andrewec

回答:


120

メインの下views.pyに、次の2つのビューの独自のカスタム実装を追加し、表示する内容でテンプレート404.html500.htmlを設定します。

このソリューションでは、カスタムコードを追加する必要はありません urls.py

これがコードです:

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

更新

handler404およびにhandler500あるエクスポートされたDjango文字列構成変数ですdjango/conf/urls/__init__.py。上記の設定が機能するのはそのためです。

上記の設定を機能させるには、urls.pyファイルで次の変数を定義し、エクスポートされたDjango変数に、これらのDjango機能ビューが定義されている場所の文字列Pythonパスを指定する必要があります。

# project/urls.py

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

Django 2.0の更新

ハンドラービューのシグネチャは、Django 2.0で変更されました:https : //docs.djangoproject.com/en/2.0/ref/views/#error-views

上記のようにビューを使用すると、handler404は次のメッセージで失敗します。

「handler404()が予期しないキーワード引数 'exception'を取得しました」

このような場合は、次のようにビューを変更してください。

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

これは私には非常にうまく機能しているように見えましたが、何らかの理由でrequest.userは404テンプレートでは問題なく表示されますが、500テンプレートではまったく表示されません(これらはほとんど同じです)-これに関する質問はこちら:stackoverflow.com/質問/ 26043211 /…
重力墓

1
私が疑問に思っていたもう1つのこと-管理バックエンドを使用していて、それらに個別のテンプレートを使用したい場合はどうなりますか?私の知る限りでは、管理者がオーバーライドして、コードのこのビットを置くためにviews.pyを持っていません。
重力墓

11
@GravityGraveは、500サーバーエラーを報告しているため500 templateレンダリングrequest.userできません。サーバーは何も提供できません。
アーロンLelevier 2014

5
django 1.9では動作しませんでした;(たぶん私は何か間違っているのでしょう。handler404djangoは予約名ですか?djangoはそのビューを正確に呼び出す必要があることをどのように知るのですか?
deathangel908

1
コメントをもとに回答を更新しました。更新が遅れてすみません。これがお役に立てば幸いです。
アーロンLelevier

71

公式回答:

カスタムエラービューの設定方法に関する公式ドキュメントへのリンクは次のとおりです。

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

それはあなたのURLconfにこれらのような行を追加することを言います(他の場所にそれらを設定しても効果はありません):

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'

設定を変更して、CSRFエラービューをカスタマイズすることもできますCSRF_FAILURE_VIEW

デフォルトのエラーハンドラ:

デフォルトのエラーハンドラのドキュメントを読むことの価値は、page_not_foundserver_errorpermission_deniedbad_request。彼らはそれぞれ、それらを見つけることができる場合、デフォルトでは、彼らはこれらのテンプレートを使用:404.html500.html403.html、と400.html

だから、あなたがしたいのがかなりのエラーページを作るTEMPLATE_DIRSことなら、それらのファイルをディレクトリに作成するだけで、URLConfを編集する必要はまったくありません。ドキュメントを読んで、使用可能なコンテキスト変数を確認してください。

Django 1.10以降では、デフォルトのCSRFエラービューはテンプレートを使用し403_csrf.htmlます。

取得:

DEBUGこれらが機能するためにはFalseに設定する必要があることを忘れないでください。そうしないと、通常のデバッグハンドラーが使用されます。


1
追加しましたが、機能しません。ビューの適切な場所を指すhandler404などが追加されましたが、機能せず、デフォルトの404が引き続き表示されます。そして、はい、Debug Falseモードで1.9を使用しています
KhoPhi

Django 1.9を使用し、500.htmlなどのテンプレートを追加するだけで、標準ページの代わりにテンプレートが表示されます。簡単に修正できます。
curtisp 2016

2
Gotchaは私を助けました。それは私のsettings.pyでこれらの変更を行うことで機能し、DEBUG = FalseとALLOWED_HOSTS = ['0.0.0.0']を設定して、任意のクライアントからのhttpリクエストを受け入れます。
shaffooo

1
誰かがURLconfがどこにあるのか疑問に思っている場合に備えて、ここにあります
Arthur Tarasov

38

これらの行をurls.pyに追加します

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'

# ...

そしてカスタムビューを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
なぜhandler400それを上書きするためだけにインポートするのhandler400 = 'myapp.views.bad_request'ですか?
Flimm


5
ハンドラーをオーバーライドするためにハンドラーをここにインポートする必要はありません。
funkotron

1
は使用しないでくださいrender_to_response。ドキュメントから:「これは推奨されておらず、将来的に非推奨になる可能性があります。」
Timmy O'Mahony 2017年

ジャンゴ1.10の場合は、のようにrender_to_response廃止されるために起こっている、以下の(使用を参照してくださいrender:代わりに)stackoverflow.com/questions/44228397/...
mrdaliri

21

参照したページから:

ビュー内からHttp404を発生させると、Djangoは404エラーの処理に特化した特別なビューをロードします。これは、ルートURLconfで変数handler404を検索することで検出されます(ルートURLconfでのみです。それ以外の場所でhandler404を設定しても効果はありません)。これは、Pythonのドット構文の文字列です。通常のURLconfコールバックと同じ形式です。404ビュー自体には特別なものはありません。これは単なる通常のビューです。

だから私はあなたがあなたのurls.pyにこのようなものを追加する必要があると信じています:

handler404 = 'views.my_404_view'

そしてhandler500についても同様です。


それはマイクにどのように見えますか?今日はDjangoを使用する私の最初の日であり、まだロープにぶら下がっています
Zac

2
@JimRilye適切な500関数をビューに追加し、その変数で参照する必要があります。そのため、urlpatterns = ...行の上に、という行をhandler500 = 'views.handle500'追加def handle500(request):し、500.htmlを表示するviews.pyにa を追加します。
マイクペリー2013

18

必要なのがのときDEBUG = Falseにサイトにいくつかの派手なエラーメッセージが表示されるカスタムページを表示する場合は、404.htmlと500.htmlという名前の2つのテンプレートをテンプレートディレクトリに追加すると、404または500のときにこのカスタムページが自動的に取得されます発生します。


1
これは、次のようなものがあることを確認するだけで機能'DIRS': [os.path.join(BASE_DIR, '<project_name>/templates')]しますsettings.py。のTEMPLATESリストにあります。
エリック2017

12

ジャンゴ2. *あなたがこの構造を使用することができますviews.py

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

settings.py

DEBUG = False

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

if DEBUG is True:
    ALLOWED_HOSTS = []

ではurls.py

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

通常、私はdefault_appを作成し、サイト全体のエラー、その中のコンテキストプロセッサを処理します。


私のために働きなさい。しかし、何exceptionですか?
zeleven

ドキュメントのリンクによると:docs.djangoproject.com/en/2.1/ref/urls/…。それは書かれています:ハンドラーがリクエストと例外の引数を受け入れることを確認してください
Alouani Younes

1
Django 3.0で私のために働きました。しかし、何locals()ですか?ファイルにはのみが表示されますpass
強化

9

settings.py:

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

そしてちょうどあなたの追加404.html500.html、テンプレートフォルダ内のページを。投票アプリのテンプレートから削除404.html500.htmlます。


メッセージの使い方raise Http404('msg')stackoverflow.com/a/37109914/895245 {{ request_path }}もご利用いただけます。
Ciro Santilli郝海东冠状病六四事件法轮功


7

エラーを発生させ、エラーページでdjangoがテンプレートを読み込んでいる場所を確認します。パススタックを意味します。ベースのtemplate_dirにこれらのhtmlページを追加します500.html404.htmlます。これらのエラーが発生すると、それぞれのテンプレートファイルが自動的に読み込まれます。

400403など、他のエラーコードのページも追加できます。

この助けを願っています!!!


6

Django 3.xでは、承認された回答が機能しrender_to_responseていたバージョンからいくつかの変更が加えられただけでなく、完全に削除されたため、承認された回答は機能しません。

他にもいくつかの回答がありますが、少しわかりやすい回答を提示します。

メインurls.pyファイル:

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

yourapp/views.pyファイル:

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

ファイルにインポートrender()したことを確認しyourapp/views.pyます。

from django.shortcuts import render

補足:render_to_response()Django 2.xでは非推奨でしたが、verisでは完全に削除されました3.x


5

1行として(404汎用ページの場合):

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
そしてそれをどこで使うのですか?
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' 

これはdjango 2.0で動作します

必ずカスタム404.htmlをアプリテンプレートフォルダー内に含めてください。


4

Django 3.0

ここにリンクがありますエラービューをカスタマイズする方法のがあります

ここにリンクを表示する方法があります

urls.py(、プロジェクトフォルダ内のメイン1)、置きます:

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'

そしてそのアプリ(my_app_name)に入れます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", {})

注:error/404.htmlファイルをプロジェクト(アプリではない)テンプレートフォルダーに配置する場合のパスですtemplates/errors/404.htmlので、ファイルを目的の場所に配置し、正しいパスを記述してください。

注2:ページの再読み込み後も古いテンプレートが表示される場合は、で変更しsettings.py DEBUG=True、保存してから、再度False(サーバーを再起動して新しいファイルを収集するために)変更します。


補足:DEUB=False静的ファイルで実行している場合は提供されない可能性があるため、カスタムエラーテンプレートの変更をプレビューできないようにします。./manage.py runserver --insecureとにかくそれらを提供するために強制ジャンゴを取得するために使用します。
ロブ


3

エラーテンプレートをに移動してみてください .../Django/mysite/templates/

これについては確かですが、これらはWebサイトに対して「グローバル」である必要があると思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.