Generate a list of page links like:
First Prev 1 2 3 4 5 6 7 Next Last
To use:
- Put Paginator.py into your app directory
- Copy pagination.html to your templates directory
- pass a paginator object to your Context
- include the pagination.html template on the page you wanted paginated
Feel free to send ideas for improvement. If enough people ask, I'll package this as a single app and perhaps even make the template inclusion into a templatetag for even easier use.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | -- Paginator.py
# BetterPaginator by spankalee
# Orignal from: http://www.djangosnippets.org/snippets/219/
# Downloaded: 08/22/2007 - [email protected]
from django.core.paginator import ObjectPaginator, InvalidPage
from django.http import Http404
class Paginator(ObjectPaginator):
def __init__(self, request=None, query_set=None, current_page=1, page_size=20, padding=3 ):
from re import sub
ObjectPaginator.__init__(self, query_set, page_size)
if request is None or query_set is None:
raise Http404
self.path = sub( r'page/\d+/?$', '', request.path )
self.path = sub( r'/$', '', self.path )
self.query_str = '?' + request.GET.urlencode()
if self.query_str == '?':
self.query_str = ''
self.current_page = int( current_page )
self.page_size = page_size
start = self.current_page-1 - padding
end = self.current_page-1 + padding
if start < 0:
end += 0 - start
start = 0
if end >= self.pages:
end = self.pages-1
if end >= self.pages:
start -= end - self.pages + 1
end = self.pages-1
if start < 0:
start = 0
self.first = start+1
self.last = end+1
self.page_numbers = [ { 'page': (p+1), 'url': self.path + '/page/' + str(p+1) + '/' + self.query_str } \
for p in range( start, end+1 ) ]
self.first_url = self.path + '/page/1/' + self.query_str
self.prev_enabled = int( current_page ) > int( self.first )
self.prev_url = self.path + '/page/' + str( self.current_page - 1 ) + '/' + self.query_str
self.next_enabled = int( current_page ) < int( self.last )
self.next_url = self.path + '/page/' + str( self.current_page + 1 ) + '/' + self.query_str
self.last_url = self.path + '/page/' + str( self.pages ) + '/' + self.query_str
self.is_paginated = self.pages > 1
def get_page(self, page_num=None):
try:
if page_num is None:
return ObjectPaginator.get_page(self, self.current_page-1)
else:
return ObjectPaginator.get_page(self, page_num)
except InvalidPage:
raise Http404
-- pagination.html
{% if paginator.is_paginated %}
{% ifnotequal paginator.current_page 1 %}
<a class="pagination" href="{{ paginator.first_url }}">First</a>
{% else %}
<span class="pagination disabled">First</a>
{% endifnotequal %}
{% if paginator.prev_enabled %}
<a class="pagination" href="{{ paginator.prev_url }}">Previous</a>
{% else %}
<span class="pagination disabled">Previous</a>
{% endif %}
{% for p in paginator.page_numbers %}
{% ifequal paginator.current_page p.page %}
<span class="pagination current">{{ p.page }}</span>
{% else %}
<a href="{{ p.url }}">{{ p.page }}</a>
{% endifequal %}
{% endfor %}
of {{ paginator.pages }}
{% if paginator.next_enabled %}
<a class="pagination" href="{{ paginator.next_url }}">Next</a>
{% else %}
<span class="pagination disabled">Next</a>
{% endif %}
{% ifnotequal paginator.current_page paginator.pages %}
<a class="pagination" href="{{ paginator.last_url }}">Last</a>
{% else %}
<span class="pagination disabled">Last</a>
{% endifnotequal %}
<br>
{% endif %}
Matched: {{ paginator.hits }}
-- urls.py
url( r'^$', 'eureka.root.views.results_list' ),
url( r'^page/(?P<page>\d+)/$', 'eureka.root.views.results_list' ),
-- views.py
from eureka.root.paginator import Paginator, InvalidPage
def results_list( request, object_id=None, page=1 ):
res = MyModel.objects.all() #Or similar
#...
paginator = Paginator( request, res, page )
return render( request, 'root/result_list.html', {
'search': search,
'seq': col == 'seq',
'lib': lib,
'has_lib': lib is not None,
'paginator': paginator,
'object_list': paginator.get_page()
} )
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
I found that in the get_page method of the Paginator class, I had to change your else clause to
Note the -1. The ObjectPaginator counts from 0 and you count from 1, so I found that they were off by one otherwise.
Beyond that, it seems to work well. Thanks.
#
Please login first before commenting.