1、view重写Paginator类
from django.core.paginator import Paginator
class JuncheePaginator(Paginator):
def __init__(self, object_list, per_page, range_num=5, orphans=0, allow_empty_first_page=True):
Paginator.__init__(self, object_list, per_page, orphans, allow_empty_first_page)
self.range_num = range_num
def page(self, number):
self.page_num = number
return super(JuncheePaginator, self).page(number)
def _page_range_ext(self):
#print type(self.page_num)
#!!!坑
#type(self.page_num)==unicode导致self.page_num - i没有结果,循环直接结束
self.page_num= int(self.page_num)
num_count = 2 * self.range_num + 1
if self.num_pages <= num_count:
return range(1, self.num_pages + 1)
num_list = []
num_list.append(self.page_num)
for i in range(1, self.range_num + 1):
if self.page_num - i <= 0:
num_list.append(num_count + self.page_num - i)
else:
num_list.append(self.page_num - i)
if self.page_num + i <= self.num_pages:
num_list.append(self.page_num + i)
else:
num_list.append(self.page_num + i - num_count)
num_list.sort()
return num_list
page_range_ext = property(_page_range_ext)
2、view分页方法
def paging(request):
article = Article.objects.all().order_by('-created_time')
paginator = JuncheePaginator(article,1) # Show 25 contacts per page
page = request.GET.get('page')
try:
article = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
article = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
article = paginator.page(paginator.num_pages)
return render(request, 'blog/paging.html', {'contacts': article})
3、分页模板
{% for contact in contacts %}
{# Each "contact" is a Contact model object. #}
{{ contact.full_name|upper }}<br />
...
{{ contact.title}}
{% endfor %}
<div>
{% if contacts.has_previous %}
<a href='?page={{ contacts.previous_page_number }}'><<</a>
{% endif %}
{% for page in contacts.paginator.page_range_ext %}
{% ifequal page contacts.number %}
<a>{{ page }}</a>
{% else %}
<a href='?page={{ page }}'>{{ page }}</a>
{% endifequal %}
{% endfor %}
{% if contacts.has_next %}
<a href='?page={{ contacts.next_page_number }}'>>></a>
{% endif %}
</div>
4、url设置
urlpatterns = [
url(r'^pag$', views.paging, name='page_list')
]
init()函数不用说了吧,就是重载了一下,添加了一个range_num参数,代表在可能的情况下,当前页左右各显示多少个页标签,默认值为5。
page()函数是对父类Paginator的page()函数的重写,主要是为了记录当前页。
核心是_page_range_ext()函数,它实现了我们根据page_num的情况来返回恰当的页面列表,page_num取默认值的情况下,如果当前页是8,则我们返回的页数列表就应该是[3,4,5,6,7,8,9,10,11,12,13],但如果说是当前页是2,则会返回[1,2,3,4,5,6,7,8,9,10,11],其余的以此类推。具体算法我就不仔细分析了,大家可以参看源代码,个人感觉还可以优化,但我现在也就能用就行。