Как создать кастомную страницу 404 в Django

Ошибка 404 (Not Found) — одна из стандартных HTTP-статусов, которые браузер получает от сервера, когда запрошенный ресурс не найден. Django предоставляет стандартную страницу 404 для разработки, но на проде лучше показывать кастомную страницу, согласованную с дизайном сайта и поддерживающую доступность.
Почему кастомная страница 404 важна
- Поддерживает визуальную идентичность и доверие пользователей.
- Даёт пользователю подсказки о возможных действиях (вернуться на главную, поиск, контакты).
- Позволяет отслеживать частые ошибки (логирование, аналитика).
- Улучшает доступность и SEO-опыт при неправильных URL.
Шаг 1: Создайте view для обработки 404
Откройте файл views.py в нужном приложении и добавьте представление, которое будет рендерить шаблон 404. Оно должно принимать два аргумента: request и exception.
from django.shortcuts import render
# кастомное представление 404
def custom_404(request, exception):
return render(request, '404.html', status=404)Примечание: замените ‘404.html’ на путь к вашему шаблону, если он находится в подпапке. Аргумент exception позволяет при необходимости логировать причину 404.
Шаг 2: Создайте шаблон для 404
Создайте файл 404.html (в каталоге шаблонов вашего проекта) и оформите его в стиле остальной части сайта. Ниже — простой пример, который можно модифицировать и улучшать под ваш дизайн.
404 — Страница не найдена
😕
Упс! Страница не найдена
Страница, которую вы ищете, либо была удалена, либо её адрес изменился.
Вернуться на главную
Если проблема повторяется — свяжитесь с поддержкой.
Советы по шаблону:
- Добавьте полезные ссылки: поиск, карта сайта, контакты.
- Сохраните простую навигацию и кнопку возврата на главную.
- Укажите aria-атрибуты и текстовые альтернативы для эмодзи/картинок.
Шаг 3: Подключите handler404 в urls.py проекта
В файле urls.py на уровне проекта (там, где settings.py и manage.py в проекте) укажите обработчик 404:
handler404 = 'app_name.views.custom_404'Например, если приложение называется recipe, а view — custom_404, то:
handler404 = 'recipe.views.custom_404'Важно: определять handler404 нужно в основном urls.py проекта, а не внутри файла urls.py приложения. При этом учтите: Django использует эти обработчики только когда DEBUG = False; для локальной разработки с DEBUG = True you’ll see стандартную debug-страницу.
Шаг 4: Протестируйте локально и в staging
Запустите локальный сервер из корня проекта (там, где manage.py):
python manage.py runserverЗатем откройте несуществующий URL, например http://127.0.0.1:8000/hello. Если у вас DEBUG = True, вы увидите отладочную страницу Django. Для проверки кастомной 404-страницы временно установите DEBUG = False и настройте ALLOWED_HOSTS, либо протестируйте на staging/production окружении.
Если кастомная страница не отображается, проверьте:
- Правильно ли указан путь к шаблону в render().
- Находится ли handler404 в проектном urls.py.
- Установлен ли DEBUG = False для тестирования поведения продакшна.
Критерии приёмки
- Страница возвращает HTTP 404.
- Внешний вид соответствует гайдлайну продукта.
- Доступность: корректные aria-атрибуты, контраст текста, фокусируемые элементы.
- Логирование: все 404 события записываются в лог/аналитику при необходимости.
- Тесты: автоматические тесты проверяют отображение и статус-код.
Чек-лист по ролям
- Разработчик:
- Создал view и шаблон.
- Настроил handler404.
- Добавил тесты на статус 404.
- Тестировщик:
- Протестировал сценарии с разными URL и методами.
- Проверил доступность на мобильных устройствах.
- Дизайнер:
- Утвердил макет и тексты сообщений.
- DevOps:
- Проверил, что DEBUG = False в production.
- Убедился, что логирование/мониторинг настроены.
Тестовые сценарии и приёмка
- Переход на несуществующий URL должен вернуть код 404 и отобразить кастомную страницу.
- При включённом DEBUG в локальной среде должна показываться debug-страница — тестировать отдельно с DEBUG = False.
- Тесты автоматизации (pytest + Django client):
def test_custom_404(client):
response = client.get('/url-that-does-not-exist/')
assert response.status_code == 404
assert 'Страница не найдена' in response.content.decode('utf-8')Когда кастомная страница 404 не подойдёт
- Если вам нужно показывать подробную диагностическую информацию — в production это риск для безопасности.
- Когда страница должна быть динамичной (например, предлагать похожие ресурсы по базе данных) и это вызывает значимую нагрузку — лучше кешировать результаты.
Альтернативные подходы
- Middleware-решение: перехватывать 404 в middleware и возвращать кастомный ответ.
- Использовать CDN/облачный провайдер ошибок (например, кастомные страницы на уровне CDN) для статических сайтов.
- Рендер на стороне клиента (SPA): отлавливать 404 маршруты в роутере фронтенда и показывать страницу из SPA.
Подсказки по доступности и SEO
- Добавьте aria-label для интерактивных элементов.
- Обязательно возвращайте корректный HTTP 404 — поисковые системы это учитывают.
- Разместите ссылку на карту сайта и форму поиска, чтобы уменьшить показатель отказов.
Логирование и аналитика
- Логируйте URL, заголовки Referer и User-Agent при 404 для анализа частых проблем.
- Не логируйте персональные данные в явном виде.
Развертывание и отладка
- Помните: Django использует handler404 только при DEBUG = False.
- Для проверки в staging добавьте временно тестовый домен в ALLOWED_HOSTS.
- Убедитесь, что статические файлы доступны, если шаблон зависит от них.
Безопасность и конфиденциальность
- Не показывайте стек-трейсы или внутреннюю информацию в сообщении 404.
- В логах избегайте записи чувствительных данных (пароли, токены).
Примеры отказов и обходные пути
- Проблема: шаблон не найден — приложение вернёт стандартную 500-страницу. Решение: убедиться, что TEMPLATE_DIRS настроены и шаблон доступен.
- Проблема: handler404 не срабатывает при DEBUG = True. Решение: тестировать с DEBUG = False или на staging.
FAQ
Как сделать так, чтобы Django использовал мой handler404 при локальном тесте?
Django использует handler404 только при DEBUG = False. Для локального теста временно установите DEBUG = False и добавьте ваш хост в ALLOWED_HOSTS.
Нужно ли возвращать HTML в 404 или можно JSON?
Зависит от клиента. Для API возвращайте JSON с ошибкой и кодом 404. Для браузерных страниц — HTML.
Какие метрики полезно собирать для 404?
Частота 404 на URL, страницы-рефереры, устройства/локализация. Это помогает находить битые ссылки и UX-проблемы.
Краткое резюме
Кастомная страница 404 в Django — это комбинация: кастомный view, шаблон, указанный handler404 и корректное тестирование в среде с DEBUG = False. Правильная реализация улучшает UX, упрощает восстановление пользователей и даёт полезную аналитическую информацию.
Важно: не показывайте внутренние детали приложения пользователю и следите за доступностью.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone