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

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

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

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

Если отключить режим отладки (его ещё называют «режим разработки» или «режим разработчика»), то часть страниц вы увидите в совершенно ином виде.
Страницы ошибок (error 404, «страница не найдена» или error 500, «ошибка сервера») предустановлены в Django, но выглядят так, как будто разработчику сайта не было до них дела.
Давайте это исправим.
Если запрошенная страница не найдена, сервер возвращает код 404. Django видит этот ответ и автоматически вызывает собственную предустановленную view-функцию. Адрес этой view-функции хранится в переменной handler404 (по умолчанию это view-функция django.views.defaults.page_not_found).
Но можно создать view-функцию самостоятельно и вызвать её при ошибке 404. Для этого надо лишь перезаписать содержимое переменной handler404: передать в эту переменную имя нашей view-функции.
Точно так же дело обстоит и с обработкой прочих ошибок: для них заготовлены переменные handler400, handler403 и несколько других, в документации есть их перечень.
Импортируем переменные из модуля django.conf.urls, переопределим дефолтные переменные — и сможем вызвать собственные view-функции и шаблоны для страниц ошибок.
Указывать view-функции для таких страниц можно только в головном urls.py. Добавьте в него следующие строки:
Скопировать кодPYTHON
from django.conf.urls import handler404, handler500 handler404 = "posts.views.page_not_found" handler500 = "posts.views.server_error"
Если в вашем редакторе кода включён анализ синтаксиса, возможно, вы получите предупреждение о том, что переменные созданы, но не используются. Но мы-то знаем, что это не так.
Чтобы редактор не приставал к вам по пустякам, выполните трюк, который отключит проверку текущей строки — добавьте в неё директиву-комментарий # noqa (от NO Quality Assurance):
Скопировать кодPYTHON
from django.conf.urls import handler404, handler500 handler404 = "posts.views.page_not_found" # noqa handler500 = "posts.views.server_error" # noqa
View-функции можно положить в любое удобное место, мы сохраним их в файле posts/views.py:
Скопировать кодPYTHON
def page_not_found(request, exception): # Переменная exception содержит отладочную информацию, # выводить её в шаблон пользователской страницы 404 мы не станем return render( request, "misc/404.html", {"path": request.path}, status=404 ) def server_error(request): return render(request, "misc/500.html", status=500)
Создайте файл шаблона templates/misc/404.html и добавьте в него код:
Скопировать кодHTML
{% extends "base.html" %} {% block title %} Ошибка 404 {% endblock %} {% block content %} <main role="main" class="container"> <div class="row"> <div class="col-md-12"> <h1>Ошибка 404</h1> <p class="lead">Страница <code>{{ path }}</code> не найдена</p> <p class="lead"><a href="{% url "index"%}">Вернуться на главную</a></p> </div> </div> </main> {% endblock %}
Теперь надо создать шаблон для ошибки 500, templates/misc/500.html
Скопировать кодHTML
{% extends "base.html" %} {% block title %} Ошибка 500 {% endblock %} {% block content %} <main role="main" class="container"> <div class="row"> <div class="col-md-12"> <h1>Ошибка 500</h1> <p class="lead">Ошибка на сервере, попробуйте обновить страницу или обратиться позже</p> <p class="lead"><a href="{% url "index" %}">Вернуться на главную</a></p> </div> </div> </main> {% endblock %}
Директорию templates/misc создавать не обязательно, но с ней будет удобнее: там можно спрятать файлы, которые практически никогда не изменяются. Так они не будут мешать при работе с другими шаблонами.

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

При разработке реальных проектов вы будете публиковать их на сервере, и режим отладки нужно будет отключать. Чтобы это сделать — измените в файле settings.py значение ключа DEBUG на False.
Если обратиться к страницам сайта, размещённого на удалённом сервере, то, вполне вероятно, вы получите сообщение об ошибке: код 400 Bad Request. Это может поставить в тупик, если не учесть, что причиной ошибки бывает отсутствие в списке ALLOWED_HOSTS адреса вашего боевого сервера.
После выполнения заданий из предыдущих уроков ALLOWED_HOSTS у вас должен быть в порядке, но проверьте его ещё раз:
Скопировать кодPYTHON
DEBUG = False ALLOWED_HOSTS = [ "localhost", "127.0.0.1", "[::1]", "testserver", ]
После отключения режима разработки у вас пропадут некоторые дополнительные функции, зато вы сможете проверить работу страниц ошибок.
Для этого просто добавьте их в urls.py, например, с адресами /404 и /500.
После проверки работы шаблонов не забудьте вернуть сайт в режим разработки:
Скопировать кодPYTHON
DEBUG = True

Задание

Для своего локального проекта напишите тест: возвращает ли сервер код 404, если страница не найдена.