Создание представления для статей по тегу
Теперь мы создадим представление для фильтрации по тегу, для этого в файл views.py нашего приложения blog добавим следующий код:
from taggit.models import Tag
class PostByTagListView(ListView):
model = Post
template_name = 'blog/post_list.html'
context_object_name = 'posts'
paginate_by = 10
tag = None
def get_queryset(self):
self.tag = Tag.objects.get(slug=self.kwargs['tag'])
queryset = Post.objects.filter(tags__slug=self.tag.slug)
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = f'Статьи по тегу: {self.tag.name}'
return context
Теперь можно перейти к обработке маршрутов и к шаблону.
Обработка представления в urls.py
Далее нам необходимо добавить обработку представления в urls.py приложения blog, добавим для этого следующую строку:
from django.urls import path
from .views import PostListView, PostDetailView, PostFromCategory, PostCreateView, PostUpdateView, CommentCreateView, PostByTagListView
urlpatterns = [
path('', PostListView.as_view(), name='home'),
path('post/create/', PostCreateView.as_view(), name='post_create'),
path('post/<str:slug>/update/', PostUpdateView.as_view(), name='post_update'),
path('post/<str:slug>/', PostDetailView.as_view(), name='post_detail'),
path('post/<int:pk>/comments/create/', CommentCreateView.as_view(), name='comment_create_view'),
path('post/tags/<str:tag>/', PostByTagListView.as_view(), name='post_by_tags'), # New
path('category/<str:slug>/', PostFromCategory.as_view(), name="post_by_category"),
]
Добавление тегов в шаблон
Откроем наш файл шаблона полной статьи templates/blog/post_detail.html, и отредактируем код, добавим блок card-footer:
{% extends 'main.html' %}
{% load mptt_tags %}
{% load static %}
{% block content %}
<div class="card mb-3">
<div class="row">
<div class="col-4">
<img src="{{ post.thumbnail.url }}" class="card-img-top" alt="{{ post.title }}" />
</div>
<div class="col-8">
<div class="card-body">
<h5>{{ post.title }}</h5>
<p class="card-text">{{ post.description }}</p>
<p class="card-text">{{ post.text }}</p>
Категория: <a href="{% url 'post_by_category' post.category.slug %}">{{ post.category.title }}</a> / Добавил: {{ post.author.username }} / <small>{{ post.time_create }}</small>
</div>
</div>
</div>
{% if post.tags.all %}
<div class="card-footer border-0">
Теги записи: {% for tag in post.tags.all %} <a href="{% url 'post_by_tags' tag.slug %}">{{ tag }}</a>, {% endfor %}
</div>
{% endif %}
</div>
<div class="card border-0">
<div class="card-body">
<h5 class="card-title">
Комментарии
</h5>
{% include 'blog/comments/comments_list.html' %}
</div>
</div>
{% endblock %}
В коде выше мы сначала проверяем наличие тегов у записи, и далее выводим их в цикле.
Давайте проверим работу тегов на сайте. Запустим сервер и первым делом добавим теги для нескольких записей:
Теперь перейдем в просмотр записей:
И нажав на тег, мы перейдем к странице с просмотром записей с таким же тегом.
На этом разработка функциональности тегирования закончена, в следующих разделах мы продолжим дорабатывать наш проект.