Кастомные страницы ошибок в Django

Режим отладки проекта

Сейчас ваш проект работает в режиме отладки: при установке проекта в конфиге был автоматически выставлен флаг DEBUG=True. В этом режиме при ошибках выводится страница с технической информацией и подробным разбором строк, в которых что-то пошло не так.

Пользователям такие страницы показывать нельзя. Во-первых, это некрасиво, непонятно и бессмысленно: пользователю не нужна эта информация, исследование причин ошибок не входит в задачи посетителей. Во-вторых, это небезопасно: в отладочной информации могут содержаться ключи доступа к внешним сервисам или к базе данных.

При публикации сайта на боевом сервере режим разработки нужно отключать. Тогда при ошибках вместо отладочных страниц будут отображаться просто страницы с сообщениями об ошибке.

Страницы ошибок

Чтобы отключить режим отладки (его ещё называют «режим разработки» или «режим разработчика»), в settings.py нужно установить значение DEBUG=False. После этого страницы с ошибками вы увидите в совершенно ином виде.

В Django есть предустановленные страницы ошибок (например, для ошибки 404 — «страница не найдена» или для 403 — «запрос отклонён»); однако выглядят эти страницы так, будто разработчику сайта не было до них дела. Нельзя оставлять их в таком виде: пользователи будут неприятно изумлены.

Создадим собственные страницы ошибок; они относятся ко всему проекту, поэтому будет логично описать их view-функции и шаблоны в приложении core.

Ошибка 404: страница не найдена

Подготовим view-функцию для страницы 404:

# core/views.py
from django.shortcuts import render

def page_not_found(request, exception):
    # Переменная exception содержит отладочную информацию; 
    # выводить её в шаблон пользовательской страницы 404 мы не станем
    return render(request, 'core/404.html', {'path': request.path}, status=404)
 

Шаблон этой страницы будет таким:

# templates/core/404.html
{% extends "base.html" %}
{% block title %}Custom 404{% endblock %}
{% block content %}
  <h1>Custom 404</h1>
  <p>Страницы с адресом {{ path }} не существует</p>
  <a href="{% url 'home:index' %}"> Идите на главную</a>
{% endblock %} 

Django распознаёт ошибки и вызывает для их обработки заготовленные view-функции. Имена этих функций хранятся в специальных переменных — хендлерах (англ. handlers). Адрес view-функции с ошибкой 404 хранится в переменной handler404 (по умолчанию это view-функция django.views.defaults.page_not_found).

Хендлер можно переопределить: передать в него имя собственной view-функции. Для этого достаточно добавить в головной url-файл проекта такую строчку:

# urls.py

handler404 = 'core.views.page_not_found'
 

В результате при ошибке 404 отработает view-функция page_not_found() и отобразится кастомная страница ошибки. А уж настроить эту страницу — дело фронтендера.

Разумеется, дизайн может быть каким угодно.

Обработка прочих ошибок выполняется точно так же. В Django заготовлены переменные handler400handler403 и несколько других, в документации есть их перечень.

403: ошибка проверки CSRF, запрос отклонён

Ошибка 403 в Django появится в том случае, если при отправке формы не был отправлен csrf-токен. Страница этой ошибки кастомизируется немного иначе: view-функция и шаблон готовятся, как и для других страниц, но переопределяется не хандлер, а константа CSRF_FAILURE_VIEW в settings.py.

View-функция:

# core/views.py
from django.shortcuts import render

def csrf_failure(request, reason=''):
    return render(request, 'core/403csrf.html')
 

Шаблон:

# templates/core/403csrf.html
{% extends "base.html" %}
{% block content %}
  <h1>Custom CSRF check error. 403</h1>
{% endblock %} 

Имя view-функции, обрабатывающей ошибку 403, указывается в settings.py, в константе CSRF_FAILURE_VIEW:

PYTHON# settings.py

CSRF_FAILURE_VIEW = 'core.views.csrf_failure'
 

Включение и отключение режима отладки

При разработке реальных проектов вы будете публиковать их на сервере, при этом нужно будет отключать режим отладки. Для этого в файле settings.py нужно установить значение ключа DEBUG=False.

После отключения режима разработки у вас перестанет показываться статика. Это нормально: в «боевом режиме» Django ожидает, что статику будет раздавать специально настроенный сервер.

После отключения режима разработки может возникнуть и другая проблема: при обращении к страницам сайта может вернуться ошибка 400: Bad Request. Эта ошибка может возникнуть как на локальном компьютере, так и на удалённом сервере.

Причина — в settings.py в списке ALLOWED_HOSTS не указан адрес вашего сервера.

Проверьте этот список, в нём должны быть указаны адреса, на которых может быть размещён проект:

DEBUG = False

ALLOWED_HOSTS = [
    'localhost',
    '127.0.0.1',
    '[::1]',
    'testserver',
] 

После проверки работы шаблонов не забудьте вернуть сайт в режим разработки:

DEBUG = True 





Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: