Группировка по и фильтр по определенному полю для всех данных в Django ORM

У меня следующая модель:

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

Я ввел данные следующим образом:

>>> leo_tolstoy = Author.objects.create(name=”Leo Tolstoy”)
>>> alexandre_dumas = Author.objects.create(name=”Alexandre Dumas”)
>>> Book.objects.create(title=”War and Peace”, author=leo_tolstoy)
>>> Book.objects.create(title=”Anna Karenina”, author=leo_tolstoy)
>>> Book.objects.create(title=”Resurrection”, author=leo_tolstoy)
>>> Book.objects.create(title=”The Three Musketeer”, author=alexandre_dumas)
>>> Book.objects.create(title=”The Count of Monte Cristo”, author=alexandre_dumas)

Я хочу вывести имя автора и все книги, которые он написал. Для всех авторов, которые есть в базе данных.
Вот так:
Лев Толстой: "Война и мир", "Анна Каренина", "Воскресение"
. Александр Дюма: "Три мушкетера", "Граф Монте-Кристо"

Я хочу найти лучшее решение для этого, но не могу найти много. Любая помощь будет оценена по достоинству, я совсем новичок в этом.

Вы можете сделать ListView из Author с помощью:

from django.views.generic.list import ListView

class AuthorListView(ListView):
    model = Author
    queryset = Author.objects.prefetch_related('book_set')
    template_name = 'app_name/author_list.html'

и затем в шаблоне (app_name/templates/app_name/author_list.html), где вы выводите авторов с:

<ul>
{% for author in object_list %}
    <li> {{ author.name }}
    <ul>
    {% for book in author.book_set.all %}
        <li>{{ book.title }}</li>
    {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

Мы можем это сделать...

Но когда вы говорите "я хочу печатать", я уверен, что вы имеете в виду гораздо больше, чем это! Но, ради ответа, вот вам:

values = Author.objects.values('name', 'book_set__title')
leo = values.filter(name='Leo Tolstoy')
alex = values.filter(name='Alexandre Dumas')
print(f'{leo["name"]}: {", ".join(leo["book_set__title"]}')
print(f'{alex["name"]}: {", ".join(alex["book_set__title"]}')
Вернуться на верх