Курс по Django: https://stepik.org/a/183363
Архив проекта: 07_sitewomen.zip
Мы продолжаем тему URL. Те из вас, кто занимался веб-разработкой, знают, что структура URL-адреса может
содержать дополнительные параметры в GET-запросах. Например, вот так:
http://127.0.0.1:8000/?name=Gagarina&cat=music
или так:
http://127.0.0.1:8000/cats/music/?name=Gagarina&type=pop
И так далее.
Здесь у нас идет специальный стартовый символ – знак вопроса, после которого
через амперсанд перечисляются различные параметры в виде пар ключ-значение. Так,
через адресную строку можно передавать произвольные данные на сервер в виде таких
GET-запросов.
Следующий
вопрос, как можно выделять эти значения и обрабатывать их на стороне сервера в
функциях представления? Для этого, как раз и существует параметр request – ссылка на
объект HttpRequest. Через него мы можем
обратиться к специальному словарю:
request.GET
где и хранятся все
эти данные.
Поправим функцию
представления categories_by_slug для отображения
словаря GET в консоль:
def categories_by_slug(request, cat_slug):
print(request.GET)
return HttpResponse(f"<h1>Статьи по категориям</h1><p >slug: {cat_slug}</p>")
И выполним,
например, такой запрос:
127.0.0.1:8000/cats/music/?name=Gagarina&type=pop
В консоли увидим значения:
<QueryDict: {'name': ['Gagarina'], 'type': ['pop']}>
Или, можем
сначала проверить: есть ли в словаре какие-либо данные и только потом выводить
их в консоль:
def categories_by_slug(request, cat_slug):
if request.GET:
print(request.GET)
return HttpResponse(f"<h1>Статьи по категориям</h1><p >slug: {cat_slug}</p>")
Как видите,
проверка делается очень просто. В дальнейшем мы будем использовать этот
функционал.
Помимо GET-запросов в
веб-программировании часто используются и POST-запросы. Они,
обычно, связаны с передачей данных из форм и позже мы их тоже будем
использовать. Здесь же я просто отмечу, что в этом случае вместо коллекции GET используется
коллекция POST, а все
остальное остается без изменений:
def categories_by_slug(request, cat_slug):
if request.POST:
print(request.POST)
return HttpResponse(f"<h1>Статьи по категориям</h1>slug: {cat_slug}</p>")
Обработка исключений при запросах к серверу
Следующий важный
аспект – это обработка исключений при запросах к серверу. Самым
распространенным из них является обращение к несуществующей странице, когда
сервер возвращает страницу с кодом 404. Например, если для нашего сайта указать
путь:
http://127.0.0.1:8000/aaa
то мы увидим
исключение 404 – страница не найдена. Такую информацию мы видим исключительно в
процессе отладки нашего сайта, когда глобальная константа DEBUG в пакете
конфигурации (файл settings.py) установлена в True.
Давайте
посмотрим, что произойдет, если временно перевести ее в значение False. Перейдем в
пакет конфигурации, откроем файл settings.py, найдем
константу DEBUG и присвоим ей
значение False. При запуске
тестового сервера у нас возникнет ошибка, что мы должны указать разрешенные
хосты. Так как мы сейчас используем хост 127.0.0.1, то его в виде строки и
укажем:
ALLOWED_HOSTS = ['127.0.0.1']
Теперь сервер
успешно запустился и при обновлении страницы мы уже видим более дружественную
страницу без лишней отладочной информации. Но как нам ее поправить, чтобы
отобразить более понятную информацию? Для этого в файле urls.py пакета
конфигурации можно переопределить обработчик исключения 404. Для этого ему
достаточно присвоить ссылку на функцию, которая и будет формировать ответ для
отсутствующих страниц, например, так:
handler404 = page_not_found
Мы здесь
передаем ссылку на функцию page_not_found, а саму функцию определим в
приложении women:
def page_not_found(request, exception):
return HttpResponseNotFound('<h1>Страница не найдена</h1>')
Обратите
внимание, функция принимает два аргумента и возвращает ответ в виде экземпляра
класса HttpResponseNotFound, которому
передается HTML-страница,
отображаемая при неверных запросах. Если теперь мы обновим страницу, то увидим
заголовок «Страница не найдена».
В дальнейшем мы
увидим, как вместо строки можно возвращать шаблон страницы 404. Сейчас главное
понять принцип работы механизма обработки исключений.
Итак, мы
предполагаем, что функция page_not_found будет вызываться всякий раз при
возникновении исключения 404. И это важный момент. Смотрите, если в какой-либо
другой функции представления сгенерировать это исключение, то будет
автоматическое перенаправление на функцию page_not_found и пользователь увидит
все ту же страницу 404. Например, в функции archive мы сделаем
проверку:
from django.http import HttpResponse, HttpResponseNotFound, Http404
def archive(request, year):
if year > 2023:
raise Http404()
return HttpResponse(f"<h1>Архив по годам</h1><p >{year}</p>")
Если год больше
2023-го, то генерируется исключение 404 как экземпляр класса Http404 и
выполняется перенаправление на функцию page_not_found. Это нам позволяет
описывать логику отображения неверных запросов в одном месте программы – в
функции page_not_found.
Аналогичным
образом можно переопределять обработчики других исключений, например:
- handler500 –
ошибка сервера;
- handler403 –
доступ запрещен;
- handler400 –
невозможно обработать запрос.
https://docs.djangoproject.com/en/4.2/ref/urls/
Но все они
работают в боевом режиме при DEBUG = False. При отладке мы
увидим расширенную служебную информацию, помогающую исправлять ошибки при
разработке сайта.
Курс по Django: https://stepik.org/a/183363