I need help with pagination. My problem is that I need pagination on nested lists. If anyone can help me here I would greatly appreciate it.
Given list [ [1,2,3],[4],[5,6]], I need a way to paginate & spit back partial lists. I have categories, and products in those categories. If user wants to see all products in the “red-wine” category, the paginator needs to paginate products over several child categories.
Category “Red-Wine” might have child category “Malbec” which has 10 products, and category “Bonarda” which has 3 products. If I set number per page at 11, I need the full Malbec category and Bonarda with only 1 product.
In my example below I end up flattening the entire Red-Wine category list to a single list with all products.
I paginate that list, and THEN re-create the category structure. It looks terrible.
Flattening the category list:
data = list(category.product_set.all())
for cat in category.get_all_children():
data.extend(cat.product_set.all())
This gets all products related to the main category.
Now I need to paginate that flattened list by some number defined in the url:
p = Paginator(data, paginate_by)
Then, to have category names show up in groups in the template (as opposed to for each product), like so:
Category1
Product1
Product2
Category2
Product3
Category3
I wrote some disgusting stuff to paginate into categories.
I made a class to fake a category + children products.
class cat():
def __init__(self, category, products):
self.category = category
self.products = products
Then, a loop to find which products are children of what and re-create the Category -> category.product_set structure of the original queryset.
temp =[]
result = []
for product in page.object_list #(this is the paginated and flattened list of objects)
if product.main_category not in temp:
temp.append(product.main_category)
product_group = []
for prod in page.object_list:
if prod.main_category == product.main_category:
product_group.append(prod)
result.append(cat(product.main_category.name, product_group))
which leaves you with something that you can use in a template like:
{% for cat in category %}
{{ cat.name }}
{% for product in cat.product %}
{{ product.name }}
{{ product.image }}
{% endfor %}
{% endfor %}
It works, but I suspect it is very inefficient. Any solutions?
Should I doing something more like checking the amount of products in each category and only modifying the last category that must be split into smaller groups?
Paginate_by = 2
len(category_1) = 1 # check, keep as is.
len(category_2) = 5
now split category_2?