Here is an example; scroll down to see the paginator.
Django’s generic views already have awesome support for pagination. But they don’t give you a great way of providing a good paginator; that is up to you to create.
They give you an array (page_range) in your templates that you can loop over to display a nice paginator but when the database gets full, do you really want to display every single page? Google shows you 10 pages to start, and bumps that up to 20 later. Flickr shows you some and then has a “…” with a final link to the last few. I wanted to do something similar.
My first attempt involved looping over page_range and checking if each page was within 2 from the current page. This worked alright, but I realized that once page_range grew to hundreds of pages I’d start seeing some slow down.
So instead I wrote a custom filter that will shrink page_range down to 2 pages before and 2 pages after the current page. Refer to this post on how to make a custom filter. Here is the code:
@register.filter def shrink(value, arg): left = arg - 3 right = arg + 2 if left < 0: left = 0 right = 5 if right > len(value): right = len(value) + 1 left = right - 6 if left < 0: left = 0 return value[left:right]
I’m sure someone can come up with a better way of doing that but it works very well for me. Basically, if you pass in value of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and an arg of 5 then it will return [3, 4, 5, 6, 7]. If you pass in 10 then it will return [6, 7, 8, 9, 10]. It will always give you an array containing at most 5 items and will try it’s hardest to center on the page you pass into it.
Spruce up the templates a bit by adding some padding to the links (so they are easier to click on), separating the First/Last/Next/Previous links from the numbers, and don’t display unnecessary links and you’ve got one beautiful paginator.

Add New Comment
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Add New Comment
Trackbacks