Django is a civilized way to build web applications. Pagination is a civilized way to display lots of data. There are still people developing websites with tens of thousands of items crammed in a single page. Even if you use JavaScript to paginate client-side, never ending download results in poor user experience.
Django has pagination support built-in. All you need to do is to wrap your QuerySet with django.core.paginator.Paginator and add paginator.page(some_page_number) to your template context. Then you can use attributes/methods such as has_next and num_pages or iterate over page_range to display your pagination navigation. To access items in current page you can use object_list, which is in fact a QuerySet sliced with correct limits. That also means; only those items that you want to display are queried. It’s all documented well as usual.
Django-pagination Takes It One Step Further
In my opinion pagination belongs to presentation. If you have many queries/views to paginate, you might find yourself repetitively writing pagination code. You can move all your pagination code into the template with django-pagination. This is accomplished with a middleware and a set of template tags.
With django-pagination you can paginate your results like this:
{% autopaginate object_list %}
{% for object in object_list %}
{{ object }}
{% endfor %}
{% paginate %}
autopaginate tag replaces your QuerySet with a paginator and paginate tag renders pagination/pagination.html template with correct values.
You can download django-pagination from Google Code, but appereantly development is moved to GitHub. I wish there was a message left on the Google Code page.
A Little SEO Shouldn’t Hurt
When you have a paginated view, you usually display the results of the first page if the pagination variable is missing. As a result /some_view/ and /some_view/?page=1 return identical responses. This might be interpreted by search engines as a duplicate. My solution for this is to redirect the first page to the page without a page variable:
1 from django.http import HttpResponsePermanentRedirect
2 from pagination.middleware import PaginationMiddleware
3
4 class SEOPaginationMiddleware(PaginationMiddleware):
5 def process_request(self, request):
6 if request.method == 'GET':
7 try:
8 page = int(request.GET['page'])
9 except (KeyError, ValueError, TypeError):
10 page = None
11 if page == 1:
12 params = request.GET.copy()
13 del(params['page'])
14 path = request.path
15 if params:
16 path += '?' + params.urlencode()
17 return HttpResponsePermanentRedirect(path)
18 return super(SEOPaginationMiddleware, self).process_request(request)
This works only if your page variable is an URL parameter (i.e. you are using GET).
Related posts:
- My PyCon APAC 2011 Presentation: Optimizing Media Performance with django_compressor
- Working with files in Django – Part 1
- Working with files in Django – Part 2
- Working with files in Django – Part 3
- Drawing Gradients with PyGame
[Django](http://www.djangoproject.com) is a civilized way to build web applications. Pagination is a civilized way to display lots of data. There are still people developing websites with tens of thousands of items crammed in a single page. Even if you use JavaScript to paginate client-side, never ending download results in poor user experience.
Django has [pagination](http://docs.djangoproject.com/en/dev/topics/pagination/) support built-in. All you need to do is to wrap your `QuerySet` with `django.core.paginator.Paginator` and add `paginator.page(some_page_number)` to your template context. Then you can use attributes/methods such as `has_next` and `num_pages` or iterate over `page_range` to display your pagination navigation. To access items in current page you can use `object_list`, which is in fact a `QuerySet` sliced with correct limits. That also means; only those items that you want to display are queried. It's all [documented well](http://docs.djangoproject.com/en/dev/topics/pagination/) as usual.
### Django-pagination Takes It One Step Further
In my opinion pagination belongs to presentation. If you have many queries/views to paginate, you might find yourself repetitively writing pagination code. You can move all your pagination code into the template with [django-pagination](http://code.google.com/p/django-pagination/). This is accomplished with a middleware and a set of template tags.
With django-pagination you can paginate your results like this:
{% autopaginate object_list %}
{% for object in object_list %}
{{ object }}
{% endfor %}
{% paginate %}
`autopaginate` tag replaces your `QuerySet` with a paginator and `paginate` tag renders `pagination/pagination.html` template with correct values.
You can download django-pagination from [Google Code](http://code.google.com/p/django-pagination/downloads/list), but appereantly development is moved to [GitHub](http://github.com/ericflo/django-pagination/tree/master). I wish there was a message left on the Google Code page.
### A Little SEO Shouldn't Hurt
When you have a paginated view, you usually display the results of the first page if the pagination variable is missing. As a result `/some_view/` and `/some_view/?page=1` return identical responses. This might be interpreted by search engines as a duplicate. My solution for this is to redirect the first page to the page without a page variable:
1 from django.http import HttpResponsePermanentRedirect
2 from pagination.middleware import PaginationMiddleware
3
4 class SEOPaginationMiddleware(PaginationMiddleware):
5 def process_request(self, request):
6 if request.method == 'GET':
7 try:
8 page = int(request.GET['page'])
9 except (KeyError, ValueError, TypeError):
10 page = None
11 if page == 1:
12 params = request.GET.copy()
13 del(params['page'])
14 path = request.path
15 if params:
16 path += '?' + params.urlencode()
17 return HttpResponsePermanentRedirect(path)
18 return super(SEOPaginationMiddleware, self).process_request(request)
This works only if your page variable is an URL parameter (i.e. you are using `GET`).
Tags: django, pagination, python, template
This entry was posted
on Monday, August 31st, 2009 at 11:05 and is filed under Programming.
You can follow any responses to this entry through the RSS 2.0 feed.
Both comments and pings are currently closed.
Dear Muhuk,
Can you direct me to a good example of “Paginated” page?
Then I may have a little chance of understanding how it handles lots of data.
Thanks.
@Efe: There’s little known site named Google, if you run a query on that you’ll see a nice example of pagination.