Django: Вывод результатов кверисетов в алфавитные заголовки

Я пытаюсь перечислить результаты запроса 'Articles' в алфавитных рубриках на основе названия статьи, например:

A

  • Яблоки
  • Антееды

B

  • Пчелы
  • Летучие мыши

etc

Я знаю, что могу сделать это вручную с помощью наборов запросов и фильтров в представлении, но есть ли более питонический подход к этому? Моя первоначальная мысль была о паре циклов for в шаблоне, один с алфавитом, другой со статьями, с чем-то вроде {% if article.startwith({{ letter}}) %}, но я не думаю, что это включено в язык шаблонов Django.

Модель:

class Article(models.Model):
title = models.CharField(max_length=200)
tagline = models.CharField(max_length=75, blank=False, default='Required')
author = models.ForeignKey(
    get_user_model(),
    on_delete=models.SET_NULL,
    null = True
    )
created = models.DateTimeField(auto_now_add=True)
department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True, blank=True)
tags = TaggableManager()
banner_image = models.ImageField(upload_to='wiki_images/banners', null=True, blank=True)
body = models.TextField()

Я также рассматривал тег Django regroup, но не могу понять, как передать ему первую букву названия каждой статьи.

На этом проекте работает Django 3.1. edit: Typo

Использование перегруппировки - хорошая идея!

Но чтобы было на что группировать, нам также нужно аннотировать наш набор запросов первой буквой, чтобы было на что группировать.

попробуйте это:

from django.db.models.functions import Substr, Upper

articles = Article.objects.annotate(first_letter=Upper(Substr('title', 1, 1)))

Тогда в шаблоне

{% regroup articles by first_letter as first_letter_articles %}
{% for first_letter in first_letter_articles %}
    <li>{{ first_letter.grouper }}
    <ul>
        {% for article in first_letter.list %}
          <li>{{ article.title }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
Вернуться на верх