chirag
chirag

Reputation: 173

Group by and filter by on a particular field for all data in Django ORM

I have following model:

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)

I have entered data like:

>>> 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)

I want to print the author’s name and all the books he wrote. For all the authors we have in the database.
Like this:
Leo Tolstoy: “War and Peace”, “Anna Karenina”, “Resurrection”
Alexandre Dumas: “The Three Musketeers”, “The Count of Monte Cristo”

I want to find the best solution for it but cannot find much. Any sort of help will be appreciated, I'm quite new to this.

Upvotes: 1

Views: 119

Answers (2)

Swift
Swift

Reputation: 1711

We can do this...

But when you say "i want to print" im sure you mean much more than that! But, for the sake of an answer, here you are:

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"]}')

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477170

You can make a ListView of the Authors with:

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'

and then in the template (app_name/templates/app_name/author_list.html) where you render the authors with:

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

Upvotes: 2

Related Questions