Курс по Django: https://stepik.org/a/183363
Архив проекта: 13_sitewomen.zip
Следующий важный
шаг при разработке шаблонов – научиться правильно прописывать URL-адреса для
ссылок. Я напомню, что ссылки в HTML-документе формируются с помощью тега <a> по
следующему правилу:
<a href="URL-адрес страницы">Название
ссылки</a>
Например, мы
можем в шаблоне index.html добавить ссылки
для чтения поста следующим образом:
<ul>
{% for p in posts %}
{% if p.is_published %}
<li>
<h2>{{p.title}}</h2>
<p >{{p.content}}</p>
<p ><a href="post/{{p.id}}/">Читать пост</a></p>
{% if not forloop.last %}
<hr>
{% endif %}
</li>
{% endif %}
{% endfor %}
</ul>
Здесь p.id – это
уникальный идентификатор статьи (мы его прописывали в коллекции data_db). При переходе
на главную страницу под каждой статьей увидим ссылку:
Однако такой
прямолинейный подход к описанию ссылок непосредственно в шаблоне – не лучший
ход, сродни с хардкодингом. Например, если в будущем изменится шаблон URL-адреса для
отображения статей, то изменения придется вносить во все шаблоны, где этот
адрес прописан. А это, как вы понимаете, неэффективно и коряво. Было бы гораздо
лучше динамически формировать URL-адреса, используя названия URL-шаблонов,
которые мы прописывали в файле urls.py приложения women:
urlpatterns = [
path('', views.index, name='home'),
path('about/', views.about, name='about'),
path('cats/<int:cat_id>/', views.categories, name='cats_id'),
path('cats/<slug:cat_slug>/', views.categories_by_slug, name='cats'),
path('archive/<year4:year>/', views.archive, name='archive'),
]
Давайте здесь
опишем три следующих маршрута:
urlpatterns = [
path('', views.index, name='home'),
path('about/', views.about, name='about'),
path('post/<int:post_id>/', views.show_post, name='post'),
]
Каждый маршрут
имеет свое имя, которым мы в дальнейшем и будем пользоваться. Конечно,
предполагается, что имена остаются неизменными на протяжении разработки всего
проекта.
Добавим функцию
представления show_post в модуль views.py приложения women, а другие не
нужные функции удалим:
def show_post(request, post_id):
return HttpResponse(f"Отображение статьи с id = {post_id}")
После этого
перейдем в шаблон index.html и в нем
сформируем URL-адреса для
каждой статьи с помощью специального шаблонного тега url, который
подробно описан на странице документации:
https://docs.djangoproject.com/en/4.2/ref/templates/builtins/
В частности, в
шаблоне index.html нам нужно
прописать следующее:
<p ><a href="{% url 'post' p.id %}">Читать пост</a></p>
То есть, после
тега url указывается имя
маршрута ‘post’, а затем,
через пробел аргумент p.id для формирования
этого маршрута. Почему именно так? На самом деле тег url работает
аналогично известной нам функции reverse. Если мы ее запишем в виде:
reverse('post', args=(11, )) # '/post/11/'
то получим
маршрут '/post/11/'. И тот же
эффект получаем от применения тега url:
Как видите, это
гораздо более удобное решение для формирования URL-адресов. Если в
будущем маршруты в файле urls.py изменятся, то
изменения автоматически произойдут и в шаблоне. Ничего дополнительно редактировать
не придется. В этом основное удобство использования шаблонного тега url.
Давайте в
заключение добавим ссылки для главного меню сайта и отобразим его в HTML-документе.
Вначале в файле urls.py мы пропишем следующие маршруты:
urlpatterns = [
path('', views.index, name='home'),
path('about/', views.about, name='about'),
path('addpage/', views.addpage, name='add_page'),
path('contact/', views.contact, name='contact'),
path('login/', views.login, name='login'),
path('post/<int:post_id>/', views.show_post, name='post'),
]
А коллекцию menu изменим, добавив
в нее информацию об именах маршрутов (в файле views.py):
menu = [{'title': "О сайте", 'url_name': 'about'},
{'title': "Добавить статью", 'url_name': 'add_page'},
{'title': "Обратная связь", 'url_name': 'contact'},
{'title': "Войти", 'url_name': 'login'}
]
Также здесь
сразу пропишем функции-заглушки для каждого пункта меню:
def addpage(request):
return HttpResponse("Добавление статьи")
def contact(request):
return HttpResponse("Обратная связь")
def login(request):
return HttpResponse("Авторизация")
Осталось в файле
index.html выполнить
отображение меню. Я сделаю это следующим образом:
<ul>
<li><a href="{% url 'home' %}">Главная</a></li>
{% for m in menu %}
{% if not forloop.last %}<li>{% else %}<li class="last">{% endif %}
<a href="{% url m.url_name %}">{{m.title}}</a>
</li>
{% endfor %}
</ul>
После обновления
главной страницы увидим список из ссылок пунктов главного меню сайта.
Курс по Django: https://stepik.org/a/183363