Home > Blockchain >  How to group a model data based on another model and paginate in django?
How to group a model data based on another model and paginate in django?

Time:03-01

I have two models:

  1. Category - Zero or multiple books can be in one category
  2. Book - A book can have zero or one category

if I do Book.objects.all() I'll get something like [book11, book10, book9, ...] normally but I don't want that. What I want is something like:

[
 [book11, book2, book1],
 [book10],
 [book8, book6],
 [book7],
 [book4, book3],
 ...
]

Where

  • Books are grouped according to their category. The books that don't have a category will also include in the list as a single element group
  • Ordering would be according to book's creation in reverse

For better understanding here is my model structure:

class Category(models.Model):
    name = models.CharField(max_length=50)

class Book(models.Model):
    name = models.CharField(max_length=128)
    category = models.ForeignKey(Category, on_delete=models.CASCADE,related_name='books', null=True, blank=True)

CodePudding user response:

To do this grouping in Python code you can use itertools.groupby

from itertools import groupby


qs = Book.objects.order_by('category', '-created_at')
grouped_books = groupby(qs, lambda book: book.category)
for category, books in grouped_books:
    print(category)
    print(list(books))

You can also do this in a template using the regroup tag

In your view pass this queryset to your template context

   books = Book.objects.order_by('category', '-created_at')

In your template

{% regroup books by category as category_list %}

<ul>
{% for category in category_list %}
    <li>{{ category.grouper }}
    <ul>
        {% for book in category.list %}
          <li>{{ book }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

CodePudding user response:

It can be achieved through field lookups of django.

template_file

<a href="{% url 'myview' category %}"> Detail</a>

urls.py

path('detail/<int:category_id>/',views.myview,name='myview')

views.py

def myview(request,cateory_id):
    records = Book.objects.filter(category=category_id)
    context={'book_records':records}
    return render(request,'appname/anyfile.html',context)
  • Related