Джанго, створивши власну сторінку помилок 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 / anlls / 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'),
)

Я можу розмістити будь-який інший необхідний код, але що мені потрібно змінити, щоб отримати власну сторінку помилок 500, якщо я використовую поганий URL?

Редагувати

РІШЕННЯ: У мене був додатковий

TEMPLATE_DIRS

в моїх налаштуваннях.py і це спричинило проблему


1
У моєму коді налагодження встановлено на помилкове
Зак

Це може допомогти вам stackoverflow.com/a/12180499/1628832
karthikr

1
Знайшов цю відповідь, шукаючи спосіб зробити лише спеціальний шаблон, і я хотів поділитися трохи документації Django, яка мені дуже допомогла; docs.djangoproject.com/en/1.7/ref/views/…
Blackeagle52

Шахта працювала без налаштування template_dirs.
Програмуваннявже

1
Бали за іронію, коли посилання в першому рядку веде до 404 сторінки Джанго. Я думаю, що веде на сторінку підручника для версії Джанго, яка не існує. Ось посилання на сторінку підручника для Django 2.0: docs.djangoproject.com/en/2.0/intro/tutorial03
andrewec

Відповіді:


120

Під основним views.pyдодайте власну власну реалізацію наступних двох представлень і просто налаштуйте шаблони 404.html та 500.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 на шлях рядка Python, де визначено ці функціональні представлення Django, як-от так:

# 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 () отримав несподіваний аргумент ключового слова" виняток ""

У такому випадку змініть свої погляди так:

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
Ще мені щось цікаво - що робити, якщо ви використовуєте адміністратор бекенда і хочете використовувати окремі шаблони для них? Наскільки мені відомо, у адміністратора немає view.py, щоб переосмислити і поставити цей біт коду.
Gravity Grave

11
@GravityGrave 500 templateне візуалізує, request.userоскільки повідомляє про 500-серверну помилку, тому сервер не може нічого обслуговувати.
Аарон Лелев'є

5
Не працювало для мене з django 1.9; (Можливо, я щось роблю не так. Чи зарезервоване ім'я handler404 django? Як би django знав, що він повинен називати саме такий погляд?
deathangel908

1
Я оновив відповідь на основі вашого коментаря. Вибачте, що оновлення настільки пізно. Я сподіваюся, що це допомагає.
Аарон Лелев'є

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_found, server_error, permission_deniedі bad_request. За замовчуванням, вони використовують ці шаблони , якщо вони можуть їх знайти, відповідно: 404.html, 500.html, 403.html, і 400.html.

Отже, якщо все, що ви хочете зробити, це зробити гарні сторінки помилок, просто створіть ці файли в TEMPLATE_DIRSкаталозі, вам зовсім не потрібно редагувати URLConf. Прочитайте документацію, щоб побачити, які змінні контексту доступні.

У Django 1.10 та пізніших версіях у шаблоні перегляду помилок CSRF використовується шаблон 403_csrf.html.

Отримав:

Не забувайте, що для цього вони DEBUGповинні встановити значення False, інакше використовуються звичайні обробники налагоджень.


1
Я додав, але це не працює. Додано handler404 та інших, які вказують на потрібні місця в моїх переглядах, але це не працює, все ще бачу за замовчуванням 404. І так, я перебуваю в режимі
помилки

Використання Django 1.9 і просто додавання шаблонів 500.html і т.д. показує їх замість стандартних сторінок. Приємний простий виправлення.
curtisp

2
Готча мені допоміг. Це працювало, вносячи ці зміни в мої налаштування.py, встановіть DEBUG = False та ALLOWED_HOSTS = ['0.0.0.0'], щоб прийняти запит http від будь-якого клієнта.
shaffooo

1
Про всяк випадок, коли хтось цікавиться, де на землі є URLconf, ось він
Артур Тарасов

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. З Документів: "це не рекомендується і, швидше за все, буде застарілим у майбутньому".
Тіммі О'Махоні

Для Django 1.10, так як render_to_responseце буде застарілим, см наступним чином (використання renderзамість цього): stackoverflow.com/questions/44228397 / ...
mrdaliri

21

На сторінці, на яку ви посилаєтесь:

Коли ви піднімете Http404 зсередини представлення, Django завантажить спеціальний вигляд, присвячений обробці 404 помилок. Він знаходить це, шукаючи змінну handler404 у вашому кореневому URLconf (і лише у вашому кореневому URLconf; налаштування handler404 ніде більше не матиме ніякого ефекту), що є рядком у синтаксисі з пунктиром Python - такому ж форматі, який використовується у звичайних зворотних викликах URLconf. Сам вид 404 не має нічого особливого: це просто звичайний вигляд.

Тому я вважаю, що вам потрібно додати щось подібне до свого urls.py:

handler404 = 'views.my_404_view'

і подібне для handler500.


Як це виглядає Майк? Сьогодні це мій перший день використання Django, і я все ще звисаю на мотузки
Зак

2
@JimRilye Вам потрібно буде додати у свої представлення відповідну функцію 500, а потім посилатись на цю змінну. Отже, над urlpatterns = ...рядком додайте рядок із зазначеним словом handler500 = 'views.handle500', а потім додайте def handle500(request):до свого view.py, який відображає ваш 500.html.
Майк Пеллі

18

Якщо все, що вам потрібно, це показати користувальницькі сторінки, які містять кілька фантастичних повідомлень про помилки для вашого сайту DEBUG = False, тоді додайте два шаблони з назвою 404.html та 500.html у свою каталог шаблонів, і вони автоматично підхоплять ці користувацькі сторінки, коли 404 або 500 піднімається.


1
Це працює просто переконайтеся, що у вас є щось на кшталт: 'DIRS': [os.path.join(BASE_DIR, '<project_name>/templates')]у вашому списку TEMPLATES в settings.py.
eric

12

У Django 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.htmlта 500.htmlсторінки в папку шаблонів. видалити 404.htmlта 500.htmlз шаблонів у програмі опитування.


Як використовувати повідомлення raise Http404('msg'): stackoverflow.com/a/37109914/895245 {{ request_path }} Також доступно.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

TEMPLATE_DEBUG видалено з django2 docs.quantifiedcode.com/python-anti-patterns/django/1.8/…
Steve W

7

Зробіть помилку. На сторінці помилки з’ясуйте, звідки django завантажує шаблони. Я маю на увазі стек шляху. У базовий template_dir додайте ці сторінки html 500.html , 404.html . У разі виникнення цих помилок відповідні файли шаблонів автоматично завантажуються.

Ви також можете додавати сторінки для інших кодів помилок, наприклад, 400 та 403 .

Сподіваюся, що це допоможе !!!


6

У Джанго 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()в Джанго була застаріла, 2.xі вона була повністю вилучена в сумніві3.x .


5

Як один єдиний рядок (для 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
І де його використовувати?
Самі

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

Джанго 3.0

ось посилання як налаштувати представлення помилок

ось посилання, як відобразити подання

в urls.py (основний, у папці проекту) поставте:

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для того, щоб змусити джанго прислуговуватися до них.
Роб

4

Не потрібно додаткового перегляду. https://docs.djangoproject.com/en/3.0/ref/views/

Просто помістіть файли помилок у каталог кореневих шаблонів

  • 404.html
  • 400.html
  • 403.html
  • 500.html

І він повинен використовувати вашу сторінку помилок, коли налагодження є помилковим


3

Спробуйте перемістити шаблони помилок до .../Django/mysite/templates/?

Я зауважу щодо цього, але я думаю, що вони повинні бути "глобальними" для веб-сайту.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.