views:

417

answers:

4

Hi, everyone!

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?

A: 
totalPages = math.ceil(float(totalRecords)/recordsPerPage)

or

paginatorInstance.num_pages # this is there by default

Wasn't that hard, was it?

Prody
+1  A: 

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)

marcc
A: 

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.

Bryan McLemore
Peharps its better to subclass the built in django.core.paginator.Paginator class to add the lower_limit and the upper_limit attributes.
webgonewild
Very possible, I've not used django's in quiet a while. Also the num_pages seems to be an invalid stat from where I sit.You seem to want the total number of objects, not the total number of pages, there may be another solution for that however in django's paginator.
Bryan McLemore
+3  A: 

Don't know why everyone is complicating things so much. As the documentation shows, all these attributes are already available.

Paginator objects have a count attribute which shows the total number of objects across all pages, and Page objects have start_index and end_index properties.

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

{{ page.start_index }} to {{ page.end_index }} of {{ page.paginator.count }}.
Daniel Roseman
whoa! this is exactily what I was searching for. thanks!
webgonewild