Курс по Django: https://stepik.org/a/183363
Архив проекта: 08_sitewomen.zip
Мы продолжаем тему маршрутизации. Очень часто при развитии сайта некоторые его страницы переносятся на другой URL-адрес. И чтобы
не потерять позиции этих страниц в поисковой выдаче, поисковым системам нужно
явно указать, что страница перемещена либо временно, либо постоянно на новый URL. Это делается с
помощью перенаправлений с кодами:
- 301 – страница
перемещена на другой постоянный URL-адрес;
- 302 – страница
перемещена временно на другой URL-адрес.
Функция redirect()
В Django подобные
редиректы достаточно просто выполняются с помощью функции:
django.shortcuts.redirect
Давайте для
примера сделаем перенаправление со страницы архива, если год больше 2023:
def archive(request, year):
if year > 2023:
return redirect('/')
return HttpResponse(f"<h1>Архив по годам</h1><p >{year}</p>")
Здесь в качестве
первого параметра указывается страница, на которую происходит перенаправление,
в данном случае – это главная страница сайта. Также в файле settings.py вернем прежнее
значение параметра DEBUG:
Если теперь
выполнить запрос:
127.0.0.1:8000/archive/2024/
то мы попадем на
главную страницу с кодом перенаправления 302 (см. консоль). Если же нам нужно
указать постоянный редирект с кодом 301, то записывается дополнительный
параметр:
return redirect('/', permanent=True)
Вообще в
качестве первого аргумента функции redirect() можно
передавать не только конкретный URL, но и представление. В частности,
вместо '/' можно передать ссылку на функцию index следующим
образом:
return redirect(index, permanent=True)
В данном случае
это будет одно и то же.
Классы HttpResponseRedirect и HttpResponsePermanentRedirect
Фреймворк Django дополнительно
поддерживает классы для выполнения перенаправлений. В частности имеются два
класса:
- HttpResponseRedirect
– для редиректа с кодом 302;
- HttpResponsePermanentRedirect
– для редиректа с кодом 301
которые можно
использовать вместо функции redirect() следующим образом:
def archive(request, year):
if year > 2023:
return HttpResponseRedirect('/')
return HttpResponse(f"<h1>Архив по годам</h1><p >{year}</p>")
На самом деле функция
redirect() использует в
своей работе эти классы, но, вместе с тем, она несколько более гибкая. Поэтому
какой вариант выбирать решает сам программист, исходя из логики построения
кода.
Параметр name функции path
Однако указывать
в функции redirect, да и вообще
где бы то ни было в приложении конкретный URL-адрес (кроме их
списка в коллекции urlpatterns) – это порочная практика, или, как еще говорят –
хардкодинг. Вместо этого каждому шаблону пути можно присвоить свое уникальное
имя и использовать его в рамках всего проекта.
Давайте
определим имена для наших URL-запросов. Для этого перейдем в файл women/urls.py и в каждой
функции path пропишем
параметр name с уникальными
именами:
urlpatterns = [
path('', views.index, name='home'),
path('cats/<slug:cat_slug>/', views.categories_by_slug, name='cats'),
path('cats/<int:cat_id>/', views.categories, name='cats_id'),
re_path(r'^archive/(?P<year>[0-9]{4})/', views.archive, name='archive'),
]
Конечно, эти
имена вы можете выбрать и другие – это лишь пример. И далее, в функции redirect мы можем
выполнить перенаправление на главную страницу, указав имя home:
return redirect('home', permanent=True)
Как видите, это
гораздо понятнее и безопаснее использования конкретных URL-адресов. Если в
дальнейшем маршрут изменится, то автоматически изменится и адрес
перенаправления для home.
Функция reverse()
Если же маршрут
помимо имени содержит еще параметры, как например, маршрут ‘cats’ с параметром slug, то для
корректного перенаправления необходимо в функции redirect() вторым и
последующими аргументами передать требуемые параметры. В нашем случае это можно
сделать так:
return redirect('cats', 'music')
В результате,
функция redirect() вычислит следующий
URL:
http://127.0.0.1:8000/cats/music/
и сделает на
него перенаправление.
Но мы можем
разделить операции вычисления URL и непосредственно перенаправление. Для
этого в Django имеется функция:
django.urls.reverse()
которая
возвращает строку URL-адреса, вычисленный на основе переданного имени и
набора аргументов. Например, для вычисления адреса маршрута cats с параметром ‘music’ функцию reverse() можно вызвать
следующим образом:
url_redirect = reverse('cats', args=('music', ))
А, затем,
передать этот маршрут в функцию redirect():
return redirect(url_redirect)
или в
соответствующий класс:
return HttpResponsePermanentRedirect(url_redirect)
На этом мы
завершим введение в тему маршрутизации и обработки URL-адресов в Django. Конечно, это
лишь базовые возможности, которые предлагает данный фреймворк. Но эта база
позволит вам сделать первые шаги в создании сайтов, постепенно знакомясь с
другими возможностями Django, опираясь на его документацию
или опыт других разработчиков. Рассказать обо всем в рамках начального курса
просто нереально. Иначе это превратится в справочную информацию и большого
эффекта от такого курса уже не будет.
Курс по Django: https://stepik.org/a/183363