Django База [2023]: Simple и Inclusion теги шаблонов, вывод популярных тегов и последних комментариев 🌇 #32
В этой статье мы рассмотрим два тега шаблонов, Simple и Inclusion теги. С помощью них мы выведем в sidebar нашего Django проекта популярные теги на сайте, а также выведем последние комментарии.
Если вы хотите выразить благодарность автору сайта, статей и курса по Django, вы можете сделать это по ссылке ниже:
Simple tags - это функции, которые принимают строку (или несколько строк) и возвращают новую строку. Они могут использоваться для создания простых тегов, которые принимают параметры и возвращают фрагменты HTML-кода. Simple tags обычно используются в шаблонах для генерации HTML-кода на основе данных из модели.
Inclusion tags - это функции, которые возвращают словарь контекста и имя шаблона для включения в основной шаблон. Inclusion tags обычно используются для создания более сложных компонентов, таких как блоки новостей, пагинация или формы поиска. Они могут принимать параметры и возвращать результаты, которые можно использовать в основном шаблоне.
Добавление папки templatetags
Первое, что нам необходимо сделать, это создать папку templatetags с файлом init.py и app_tags.py, вместо app название нашего приложения. В нашем случае, мы делаем теги в приложении blog, значит название файла будет blog_tags.py.
Реализация популярных тегов с помощью simple tags
Теперь перейдем к реализации. У нас уже должен установлен пакет django-taggit, мы его устанавливали ранее в этом уроке.
В созданном файле blog_tags.py добавляем следующий фрагмент кода:
from django import template
from django.db.models import Count
from taggit.models import Tag
register = template.Library()
@register.simple_tag
def popular_tags():
tags = Tag.objects.annotate(num_times=Count('article')).order_by('-num_times')
tag_list = list(tags.values('name', 'num_times', 'slug'))
return tag_list
Данный код создает пользовательский тег для шаблонов Django с именем popular_tags, который получает список популярных тегов, отсортированных по количеству статей, содержащих эти теги. Для этого используется модуль django.db.models для выполнения запросов к базе данных Django и модель Tag из стороннего пакета django-taggit для работы с тегами.
После выполнения запроса, полученный список тегов сохраняется в переменной tag_list. Каждый элемент списка представлен в виде словаря, содержащего три ключа - name (имя тега), num_times (количество статей с этим тегом) и slug (уникальный идентификатор тега).
Этот список затем возвращается из функции popular_tags в виде контекста, который можно использовать в шаблоне для вывода списка популярных тегов.
Добавление популярных тегов в sidebar
Далее нам необходимо добавить отображение тегов в sidebar.html, для этого изменим нашу разметку:
{% load mptt_tags blog_tags %}
<div class="card mb-2">
<div class="card-body">
<h5 class="card-title">Категории</h5>
{% full_tree_for_model blog.Category as categories %}
<div class="card-text">
<ul>
{% recursetree categories %}
<li>
<a href="{{ node.get_absolute_url }}">{{ node.title }}</a>
</li>
{% if not node.is_leaf_node %}
<ul>
{% endif %} {{children}} {% if not node.is_leaf_node %}
</ul>
{% endif %} {% endrecursetree %}
</ul>
</div>
</div>
</div>
<div class="card mb-2">
<div class="card-body">
<h5 class="card-title">Популярные теги</h5>
<div class="card-text">
<ul>
{% popular_tags as tag_list %}
{% for tag in tag_list %}
<li><a href="{% url 'articles_by_tags' tag.slug %}">{{ tag.name }}</a> ({{ tag.num_times }})</li>
{% empty %}
<li>Популярных тегов не найдено.</li>
{% endfor %}
</ul>
</div>
</div>
</div>
Отлично. Проверим работу на сайте:
Вывод последних комментариев с помощью inclusion tags
Далее рассмотрим пример с inclusion tags для вывода последних комментариев, саму систему мы создавали ранее в этом уроке. В файле blog_tags.py добавим следующий код:
from django import template
from django.db.models import Count
from taggit.models import Tag
from ..models import Comment
register = template.Library()
@register.simple_tag
def popular_tags():
tags = Tag.objects.annotate(num_times=Count('article')).order_by('-num_times')
tag_list = list(tags.values('name', 'num_times', 'slug'))
return tag_list
@register.inclusion_tag('includes/latest_comments.html')
def show_latest_comments(count=5):
comments = Comment.objects.select_related('author').filter(status='published').order_by('-time_create')[:count]
return {'comments': comments}
Этот код реализует inclusion tag под названием show_latest_comments, который позволяет вывести последние опубликованные комментарии в шаблоне latest_comments.html.
Этот тег принимает аргумент count, определяющий количество комментариев для отображения. По умолчанию, это значение равно 5.
Тег использует Comment.objects.select_related('author')
, чтобы получить последние комментарии, связанные с их авторами. Фильтр filter(status='published')
используется для получения только опубликованных комментариев.
Комментарии сортируются по дате создания в обратном порядке с помощью order_by('-time_create')
.
Наконец, тег возвращает словарь comments, который содержит последние комментарии для использования в шаблоне latest_comments.html.
Шаблон для комментариев
Создаем файл в папке templates/includes с названием latest_comments.html, с разметкой:
<div class="card">
<div class="card-body">
<h5 class="card-title">Последние комментарии</h5>
<div class="card-text">
<ul>
{% for comment in comments %}
<li>{{ comment.author }} - {{ comment.content|striptags }}</li>
{% empty %}
<li>Комментариев нет.</li>
{% endfor %}
</ul>
</div>
</div>
</div>
Далее добавляем тег в sidebar.html:
{% load mptt_tags blog_tags %}
<div class="card mb-2">
<div class="card-body">
<h5 class="card-title">Категории</h5>
{% full_tree_for_model blog.Category as categories %}
<div class="card-text">
<ul>
{% recursetree categories %}
<li>
<a href="{{ node.get_absolute_url }}">{{ node.title }}</a>
</li>
{% if not node.is_leaf_node %}
<ul>
{% endif %} {{children}} {% if not node.is_leaf_node %}
</ul>
{% endif %} {% endrecursetree %}
</ul>
</div>
</div>
</div>
<div class="card mb-2">
<div class="card-body">
<h5 class="card-title">Популярные теги</h5>
<div class="card-text">
<ul>
{% popular_tags as tag_list %}
{% for tag in tag_list %}
<li><a href="{% url 'articles_by_tags' tag.slug %}">{{ tag.name }}</a> ({{ tag.num_times }})</li>
{% empty %}
<li>Популярных тегов не найдено.</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% show_latest_comments count=5 %}
Ранее мы подключили наши теги из файла blog_tags в самом верху html шаблона sidebar, поэтому в самом низу выводим просто наш созданный inclusion тег, где передаем количество выводимых комментариев, в нашем случае: 5.
Результат:
Теперь вы научились работать как с simple, так и с inclusion тегами в шаблонах.