Django — My hideous pagination solution. Help required.

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

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:

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:
  product_group = []
  for prod in page.object_list:
   if prod.main_category == product.main_category:
  result.append(cat(, product_group))

which leaves you with something that you can use in a template like:
{% for cat in category %}
{{ }}
{% for product in cat.product %}
{{ }}
{{ 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?


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s