Формирование URL-адресов в шаблонах
На данный момент мы с вами научились создавать шаблоны, прописывать в них различные теги , переменные > и фильтры <
Следующий важный шаг – научиться правильно указывать URL-адреса в наших шаблонах. На предыдущих занятиях почти у всех ссылок я ставил заглушки – символ шарп:
Пришло время сформировать полноценные ссылки на страницы. Для этого в Django используется специальный тег:
Давайте для начала пропишем с помощью этого тега маршрут к главной странице в шаблоне base.html. В нем имеется вот такая строчка:
li class="logo">a href="/">div class="logo">/div>/a>/li>
Здесь косая черта – это как раз ссылка на главную страницу. Но это не лучший подход, так как URL-адрес главной не обязательно должен совпадать с доменным именем (в нашем случае: http://127.0.0.1:8000/). Мы можем определить ее и как-то иначе, например:
И тогда везде в шаблонах придется вносить эти изменения. Гораздо практичнее и, чаще всего, так и делают, используют имена маршрутов. Если мы откроем файл women/urls.py, то увидим, что главная страница имеет имя home. Им мы и воспользуемся, указав в теге url:
li class="logo">a href="">div class="logo">/div>/a>/li>
Видите, как это удобно. Теперь, если изменить адрес главной страницы:
urlpatterns = [ path('home/', index, name='home'), path('about/', about, name='about'), ]
то ссылка на главную автоматически изменится. В этом удобство именованных ссылок.
Но вернем прежний адрес главной страницы, так будет удобнее. Добавим ссылки для нашего главного меню. Вначале переопределим список menu, указав не только заголовок, но и имя ссылки:
menu = [{'title': "О сайте", 'url_name': 'about'}, {'title': "Добавить статью", 'url_name': 'add_page'}, {'title': "Обратная связь", 'url_name': 'contact'}, {'title': "Войти", 'url_name': 'login'} ]
Затем, в файле women/urls.py сформируем маршруты к этим страницам:
urlpatterns = [ path('', index, name='home'), path('about/', about, name='about'), path('addpage/', addpage, name='add_page'), path('contact/', contact, name='contact'), path('login/', login, name='login'), ]
И в файле women/views.py пропишем указанные функции представлений:
def about(request): return render(request, 'women/about.html', {'menu': menu, 'title': 'О сайте'}) def addpage(request): return HttpResponse("Добавление статьи") def contact(request): return HttpResponse("Обратная связь") def login(request): return HttpResponse("Авторизация")
Пока это просто функции-заглушки. А вот функцию index перепишем в таком виде:
def index(request): posts = Women.objects.all() context = { 'posts': posts, 'menu': menu, 'title': 'Главная страница' } return render(request, 'women/index.html', context=context)
Смотрите, мы здесь определили отдельный словарь context, в котором указали все те параметры, что собираемся передавать шаблону index.html, а затем, в функции render передаем этот словарь с помощью именованного параметра context. Это будет эквивалентно предыдущей записи, но так текст программы читается гораздо лучше.
Осталось в самом шаблоне правильно обработать коллекцию menu. В файле шаблона base.html пропишем следующие строчки:
{% for m in menu %} {% if not forloop.last %} li>a href="">{{m.title}}/a>/li> {% else %} li class="last">a href="">{{m.title}}/a>/li> {% endif %} {% endfor %}
Теперь, при обновлении страницы мы получаем полноценные ссылки в главном меню.
Формирование динамических URL-адресов
Осталось прописать ссылки у списка наших статей. Во-первых, определим шаблон маршрута, по которому они будут доступны. Для этого в файле women/urls.py добавим строчку в urlpatterns:
path('post//', show_post, name='post'),
то есть, маршрут постов будет выглядеть так:
Конечно, в реальных проектах вместо post_id, как правило, используется строка (слаг), записанная латиницей и отражающая суть статьи. Такие ссылки лучше ранжируются поисковыми системами и понятнее пользователям сайта. Позже мы тоже будем использовать слаг, но на данном этапе нам важно разобраться, как создавать динамические URL-ссылки на уровне шаблонов.
Итак, маршрут определен, имя маршрута задано как post, осталось прописать функцию представления show_post. Мы ее пока определим вот такой заглушкой:
def show_post(request, post_id): return HttpResponse(f"Отображение статьи с style="color: black;">)
Осталось все это определить в шаблоне index.html, в котором происходит отображение списка статей. Фактически, все что нам нужно – это переписать следующую строчку:
p class="link-read-post">a href="">Читать пост/a>/p>
Смотрите, здесь в параметре href используется уже знакомый нам тег шаблона url, далее указываем имя ссылки post и через пробел ее параметр post_id в виде p.pk. Вспоминаем, что мы перебираем здесь коллекцию posts, которая хранит ссылки на объекты класса модели Women. И у этих объектов имеется параметр pk, равный идентификатору записи. Почему мы используем pk, а не id? В принципе, можно указать е его, но согласно конвенции Django, лучше использовать атрибут pk.
Если теперь обновим главную страницу, то у всех постов появятся сформированные нами ссылки и каждая будет соответствовать своей статье. Щелкая по любой из них, перейдем по адресу, например:
и увидим строчку «Отображение статьи с от функции заглушки show_post. Вот так довольно просто можно формировать различные динамические URL-адреса на уровне шаблонов.
Функция get_absolute_url()
Как я уже не раз отмечал, фреймворк Django работает согласно паттерну MTV (Models, Templates, Views), то есть, ему постоянно приходится связывать модели с шаблонами и видами, а значит, формировать URL-ссылки для выбранных записей из таблиц БД. И мы только что это делали – формировали URL-ссылки для записей модели Women. При разработке сайтов – это типовая операция. Поэтому, разработчики Django озаботились упрощением и автоматизацией этой процедуры. Что они нам предлагают? Смотрите. В классах моделей можно определять специальный метод под названием:
который бы возвращал полный URL-адрес для каждой конкретной записи (ассоциированной с текущим объектом). Например, в классе модели Women мы можем определить этот метод следующим образом:
def get_absolute_url(self): return reverse('post', kwargs={'post_id': self.pk})
Здесь используется функция reverse, которая строит текущий URL-адрес записи на основе имени маршрута post и словаря параметров kwargs. В данном случае указан один параметр post_id со значением идентификатора объекта self.pk. Разумеется, вначале нам нужно импортировать эту функцию:
from django.urls import reverse
Все, теперь при обращении к методу get_absolute_url объекта класса модели Women, мы будем получать ее URL-адрес.
Где здесь упрощение и автоматизация? Смотрите, в шаблоне index.html, при формировании ссылок статей, мы теперь можем вместо тега шаблона url указать метод get_absolute_url:
p class="link-read-post">a href=">">Читать пост/a>/p>
Вспоминаем, что p как раз ссылается на объекты класса Women, следовательно, у нее появился атрибут get_absolute_url, который мы и прописываем. И, обратите внимание, при указании этого метода, мы не пишем в конце круглые скобки, т.к. он здесь самостоятельно не вызывается. Вызов сделает функция render при обработке этого шаблона.
Почему это лучше тега url? Представьте, что в будущем мы изменили шаблон этой ссылки и стали выводить посты не по id, а по слагу. Тогда, при использовании тега url, нам пришлось бы менять эти ссылки в каждом шаблоне, заменяя self.pk на self.slug, например. В этом как раз неудобство и источник потенциальных ошибок. Теперь, с методом get_absolute_url() нам достаточно изменить маршрут в нем и это автоматически скажется на всех шаблонах, где она используется.
Второй важный момент функции get_absolute_url() заключается в том, что согласно конвенции, модули Django используют этот метод в своей работе (если он определен в модели). Например, стандартная админ-панель обращается к этому методу для построения ссылок на каждую запись наших моделей. И в дальнейшем мы увидим как это работает.
В свою очередь тег имеет смысл применять для построения ссылок не связанных с моделями или, для ссылок без параметров, используя только имена маршрутов.
Видео по теме
#1. Django — что это такое, порядок установки
#2. Модель MTV. Маршрутизация. Функции представления
#3. Маршрутизация, обработка исключений запросов, перенаправления
#4. Определение моделей. Миграции: создание и выполнение
#5. CRUD — основы ORM по работе с моделями
#6. Шаблоны (templates). Начало
#7. Подключение статических файлов. Фильтры шаблонов
#8. Формирование URL-адресов в шаблонах
#9. Создание связей между моделями через класс ForeignKey
#10. Начинаем работу с админ-панелью
#11. Пользовательские теги шаблонов
#12. Добавляем слаги (slug) к URL-адресам
#13. Использование форм, не связанных с моделями
#14. Формы, связанные с моделями. Пользовательские валидаторы
#15. Классы представлений: ListView, DetailView, CreateView
#16. Основы ORM Django за час
#17. Mixins — убираем дублирование кода
#18. Постраничная навигация (пагинация)
#19. Регистрация пользователей на сайте
#20. Делаем авторизацию пользователей на сайте
#21. Оптимизация сайта с Django Debug Toolbar
#22. Включаем кэширование данных
#23. Использование капчи captcha
#24. Тонкая настройка админ панели
#25. Начинаем развертывание Django-сайта на хостинге
#26. Завершаем развертывание Django-сайта на хостинге
© 2023 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта