Курс по Django: https://stepik.org/a/183363
Архив проекта: 29_sitewomen.zip
На этом занятии
мы с вами добавим теги на наш учебный сайт. Список всех тегов будем выводить в
сайдбаре с помощью шаблонного тега. И, кроме того, у каждой статьи также
выводить список тегов, которые к ней относятся.
Первым делом,
пропишем новый маршрут для отображения списка статей по выбранному тегу. В
файле women/urls.py в коллекцию urlpatterns
добавим строчку:
urlpatterns = [
...
path('tag/<slug:tag_slug>/', views.show_tag_postlist, name='tag'),
]
И в модели TagPost
пропишем метод get_absolute_url() для формирования URL-адреса:
class TagPost(models.Model):
tag = models.CharField(max_length=100, db_index=True)
slug = models.SlugField(max_length=255, unique=True, db_index=True)
def get_absolute_url(self):
return reverse('tag', kwargs={'tag_slug': self.slug})
def __str__(self):
return self.tag
Далее, в файле women/views.py объявим функцию
представления для нового маршрута:
def show_tag_postlist(request, tag_slug):
tag = get_object_or_404(TagPost, slug=tag_slug)
posts = tag.tags.filter(is_published=Women.Status.PUBLISHED)
data = {
'title': f'Тег: {tag.tag}',
'menu': menu,
'posts': posts,
'cat_selected': None,
}
return render(request, 'women/index.html', context=data)
Мы здесь
пытаемся получить тег по его слагу. Если это удается, то затем, читаем список
опубликованных постов, связанных с этим тегом. Ниже идет стандартное
отображение списка с помощью шаблона index.html.
Добавим в
функцию представления index() параметр cat_selected со значением 0:
def index(request):
data = {
'title': 'Главная страница',
'menu': menu,
'posts': Women.published.all(),
'cat_selected': 0,
}
return render(request, 'women/index.html', context=data)
И следующим
шагом сформируем новый шаблонный тег для отображения списка тегов в сайдбаре.
Откроем файл women/women_tags.py и
зарегистрируем еще одну функцию:
@register.inclusion_tag('women/list_tags.html')
def show_all_tags():
return {"tags": TagPost.objects.all()}
Добавим шаблон list_tags.html со следующим
содержимым:
{% if tags %}
Теги:</p>
<ul class="tags-list">
{% for t in tags %}
<li><a href="{{t.get_absolute_url}}">{{t.tag}}</a></li>
{% endfor %}
</ul>
{% endif %}
Воспользуемся
этим тегом в базовом шаблоне base.html:
...
<!-- Sidebar слева -->
<td valign="top" class="left-chapters">
<ul id="leftchapters">
{% if cat_selected == 0 or cat_selected is None %}
<li class="selected">Все категории</li>
{% else %}
<li><a href="{% url 'home' %}">Все категории</a></li>
{% endif %}
{% show_categories cat_selected %}
<li class="share">
<p >Наш канал</p>
<a class="share-yt" href="..." target="_blank" rel="nofollow"></a>
</li>
<li>{% show_all_tags %}</li>
</ul>
</td>
<!-- Конец Sidebar'а -->
...
Запустим
тестовый веб-сервер и посмотрим на результат работы сайта:
Также мы можем
кликать по тегам и смотреть список статей, связанных с ними. По некоторым тегам
не отображается ни одной статьи, но мы пока это оставим в таком виде.
Осталось
добавить список тегов, ассоциированных с каждой отдельной статьей. Для этого
перейдем в шаблон women/post.html и добавим
следующие строчки:
{% extends 'base.html' %}
{% block breadcrumbs %}
<!-- Теги -->
{% with post.tags.all as tags %}
{% if tags %}
<ul class="tags-list">
<li>Теги:</li>
{% for t in tags %}
<li><a href="{{t.get_absolute_url}}">{{t.tag}}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% endblock %}
{% block content %}
<h1>{{post.title}}</h1>
{% if post.photo %}
<p ><img class="img-article-left" src="{{post.photo.url}}"></p>
{% endif %}
{{post.content|linebreaks}}
{% endblock %}
Открываем на
сайте страницу с постом и в самом верху видим список тегов, связанных с ней.
Вот пример использования связи Many To Many.
Курс по Django: https://stepik.org/a/183363