Django База [2023]: Simple и Inclusion теги шаблонов, вывод популярных тегов и последних комментариев 🌇 #32
Django

Django База [2023]: Simple и Inclusion теги шаблонов, вывод популярных тегов и последних комментариев 🌇 #32

Теги не заданы
Razilator

В этой статье мы рассмотрим два тега шаблонов, Simple и Inclusion теги. С помощью них мы выведем в sidebar нашего 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 добавляем следующий фрагмент кода:

blog/templatetags/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, для этого изменим нашу разметку:

templates/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>

Отлично. Проверим работу на сайте:

В sidebar теперь появился список популярных тегов
В sidebar теперь появился список популярных тегов

Вывод последних комментариев с помощью inclusion tags

Далее рассмотрим пример с inclusion tags для вывода последних комментариев, саму систему мы создавали ранее в этом уроке. В файле blog_tags.py добавим следующий код:

blog/templatetags/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, с разметкой:

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:

templates/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.

Результат:

Теперь в sidebar.html добавлены последние комментарии
Теперь в sidebar.html добавлены последние комментарии

Теперь вы научились работать как с simple, так и с inclusion тегами в шаблонах.

;