Создание шаблонного тега включения
Мы создадим еще один тег, чтобы отображать последние посты на боковой панели блога. На этот раз мы реализуем тег включения. Используя тег включения, можно отображать шаблон с контекстными переменными, возвращаемыми вашим шаблонным тегом.
Отредактируйте файл templatetags/blog_tags.py, добавив следующий ниже исходный код:
@register.inclusion_tag('blog/post/latest_posts.html')
def show_latest_posts(count=5):
latest_posts = Post.published.order_by('-publish')[:count]
return {'latest_posts': latest_posts}
В приведенном выше исходном коде мы зарегистрировали шаблонный тег, применяя декоратор @register.inclusion_tag.
Используя blog/post/latest_posts.html, был указан шаблон, который будет прорисовываться возвращенными значениями.
Шаблонный тег будет принимать опциональный параметр count, который по умолчанию равен 5.
Этот параметр позволит задавать число отображаемых постов. Данная переменная используется для того, чтобы ограничивать результаты запроса Post.published.order_by('-publish')[:count].
Обратите внимание, что приведенная выше функция возвращает не простое значение, а словарь переменных. Теги включения должны возвращать словарь значений, который используется в качестве контекста для прорисовки заданного шаблона. Только созданный шаблонный тег позволяет задавать опциональное число отображаемых постов как {% show_latest_posts 3 %}.
Теперь создайте новый файл шаблона в разделе blog/post/ и назовите его latest_posts.html.
Отредактируйте новый шаблон blog/post/latest_posts.html, добавив следующий ниже исходный код:
<ul>
{% for post in latest_posts %}
<li>
<a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
В приведенном выше исходном коде отображается неупорядоченный список постов, используя возвращаемую вашим шаблонным тегом переменную latest_posts.
Теперь отредактируйте шаблон blog/base.html, добавив в самый конец наш новый шаблонный тег, чтобы отображать последние три поста, как показано ниже:
.....
<h3>Latest posts</h3>
{% show_latest_posts 3 %}
</div>
</body>
</html>
Здесь вызывается шаблонный тег, передающий число отображаемых постов, и шаблон прорисовывается прямо на месте с заданным контекстом.
Затем вернитесь в свой браузер и обновите страницу. Теперь боковая панель должна выглядеть следующим образом:
Создание шаблонного тега, возвращающего набор запросов
Наконец, мы создадим простой шаблонный тег, который возвращает значение. Мы сохраним результат в реиспользуемой переменной, не выводя его напрямую. Мы создадим тег, чтобы отображать посты с наибольшим числом комментариев.
Отредактируйте файл templatetags/blog_tags.py, добавив следующую ниже инструкцию импорта и шаблонный тег:
from django.db.models import Count
@register.simple_tag
def get_most_commented_posts(count=5):
return Post.published.annotate(
total_comments=Count('comments')
).exclude(total_comments=0).order_by('-total_comments')[:count]
В приведенном выше шаблонном теге с помощью функции annotate() формируется набор запросов QuerySet, чтобы агрегировать общее число комментариев к каждому посту.
Функция агрегирования Count используется для сохранения количества комментариев в вычисляемом поле total_comments по каждому объекту Post.
Набор запросов QuerySet упорядочивается по вычисляемому полю в убывающем порядке. Также предоставляется опциональная переменная count, чтобы ограничивать общее число возвращаемых объектов.
В дополнение к Count Django предлагает функции агрегирования Avg, Max, Min и Sum.
Подробнее о функциях агрегирования можно почитать на странице https://docs.djangoproject.com/en/5.0/topics/db/aggregation/.
Далее отредактируйте шаблон blog/base.html, добавив следующий ниже исходный код:
.......
<h3>Latest posts</h3>
{% show_latest_posts 3 %}
<h3>Most commented posts</h3>
{% get_most_commented_posts as most_commented_posts %}
<ul>
{% for post in most_commented_posts %}
<li>
<a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
</div>
</body>
</html>
В приведенном выше исходном коде результат сохраняется в конкретно прикладной переменной, используя аргумент as, за которым следует имя переменной.
В качестве шаблонного тега используется {% get_most_commented_posts as most_commented_posts %}, чтобы сохранить результат шаблонного тега в новой переменной с именем most_commented_posts.
Затем возвращенные посты отображаются, используя HTML-элемент в виде неупорядоченного списка.
Теперь откройте свой браузер и обновите страницу, чтобы увидеть итоговый результат. Он должен выглядеть следующим образом:
Теперь у вас есть четкое понимание того, как разрабатывать конкретно прикладные шаблонные теги.
Подробнее о них можно почитать на странице https://docs.djangoproject.com/en/5.0/howto/custom-template-tags/.