Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show page items count in django pagination

I'm trying to figure out how to show something like "Showing 1-10 of 52" using django pagination in my templates.

I accomplished the pagination itself but nothing comes to my mind about this requirement.
Any ideas?

like image 811
webgonewild Avatar asked Nov 06 '09 18:11

webgonewild


3 Answers

As the documentation shows, Paginator objects have a count attribute which shows the total number of objects across all pages (in the queryset or list they're paginating) and Page objects have start_index() and end_index() methods.

So, assuming you pass the page to the template context:

Showing {{ page.start_index }}-{{ page.end_index }} of {{ page.paginator.count }}
like image 172
Daniel Roseman Avatar answered Sep 17 '22 08:09

Daniel Roseman


You'll need to do something moderately more complex behind the scenes. And please note that while I am a python dev, i've been using werkzeug and jinja2 for a long time now and so my django syntax is a little rusty. Also this was dry-coded (as in I just typed it here in the browser) and should be tested to make sure that it works as intended.

Generally I'll create a pagination object, and pass it in a query object that isn't filtered by pages, you can also tell it how many per page and what page you're on.

So something vaguely similar to:

Paginator(query, objects_per_page, current_page_number)

And then pass the resulting paginator object into the template.

Inside the paginator's init you'd want to do something similar to:

def __init__(self, query, objects_per_page, current_page_number):
    self.total = query.count()

    self.per_page = objects_per_page
    self.current_page_number = current_page_number
    self.lower_limit = objects_per_page * current_page_number
    self.upper_limit = objects_per_page * (current_page_number + 1)

    if self.upper_limit > self.total:
        self.upper_limit = self.total

    self.objects = query[self.lower_limit - 1:self.upper_limit - 1]

Then in the template you'd do something like

Showing {{paginator.lower_limit}}-{{paginator.upper_limit}} of {{paginator.total}}

And later when you are ready to iterate over the objects you could just iterate over paginator.objects.

I hope that gives you a general idea of how you can cleanly do this.

like image 28
Bryan McLemore Avatar answered Sep 17 '22 08:09

Bryan McLemore


The django Paginator object has a num_pages property. In your view, you can just pass the correct data to your template and show it there.

So as an (rough) example:

view

 current_page = ## input param 
 items_per_page = 10  
 paginator = Paginator(result, items_per_page)    

 ...
 return render_to_response('template.html', 
   {
     'num_pages': paginator.num_pages,
     'start_count': items_per_page * current_page + 1,
     'end_count': (items_per_page * current_page + 1) + len(paginator(current_page).object_list)
     'items_per_page':  items_per_page
   }

template

showing {{start_count} - {{end_count}} of {{num_pages}}

(I wrote this code without the benefit of a compiler, so test it)

like image 32
marcc Avatar answered Sep 18 '22 08:09

marcc