django 分页 pagination
使用django pagination的文档比较多,但是完整整理的还是比较少的,这里完整整理一下使用django pagination的过程。
安装 django pagination
默认的pagination包不包含在django安装包里面的,所以如果直接配置,然后再使用会报找不到pagination类的错误,如下No module named pagination
。
安装方式 sudo pip install django-pagination
.
详情可参考这篇文章
配置分页程序
可以参考官方的pagination文档
也可以参考七步教你实现Django网站列表自动分页
这一步没有什么问题,按照官方指导配置即可。
django 1.9版本报新的错误
django1.9使用django-pageination出现AttributeError错误处理
问题:
在django1.9使用django-pageination出现错误
AttributeError: 'WSGIRequest' object has no attribute 'REQUEST'
原因:
HttpRequest.REQUEST在django1.7中被弃用并使用更明确的HttpRequest.GET和HttpRequest.POST来替代,而在django1.9中HttpRequest.REQUEST被移除了。
处理:
打开python安装目录下的dist-packages_pagination_middleware.py
把
return int(self.REQUEST['page'])
修改成
return int(self.POST['page'])
遗留一个问题
至此分页已经OK,但是遗留一个分页菜单的问题,光使用{% paginate %} 会报错
TypeError: sequence index must be integer, not 'slice
详细看了一下源码,在下面地方找到问题
...
try:
paginator = context['paginator']
page_obj = context['page_obj']
page_range = paginator.page_range
# Calculate the record range in the current page for display.
records = {'first': 1 + (page_obj.number - 1) * paginator.per_page}
records['last'] = records['first'] + paginator.per_page - 1
if records['last'] + paginator.orphans >= paginator.count:
records['last'] = paginator.count
# First and last are simply the first *n* pages and the last *n* pages,
# where *n* is the current window size.
first = set(list(page_range)[:window])
last = set(list(page_range)[-window:])
# Now we look around our current page, making sure that we don't wrap
# around.
current_start = page_obj.number-1-window
if current_start < 0:
current_start = 0
current_end = page_obj.number-1+window
if current_end < 0:
current_end = 0
current = set(list(page_range)[current_start:current_end])
pages = []
...
默认的代码是
first = set(page_range[:window])
last = set(page_range[-window:])
这个在当前版本是不能执行的,所以修改为上面的就好了。
django 1.9的 paginate。
django 1.9版本用原始的配置发现可以进行分页,但是按页数显示不同的是有问题的,应该是django1.9版本的升级导致的,也暂时没有看源码,直接修改用官方给出的表现方式来配置。
前台代码为:
{% block maincontent %}
<section class="content">
{% if latest_entry_list %}
{% for entry in latest_entry_list %}
<article class="post">
<div class="date-wrapper">
<div class="date-value">{{ entry.publication_date.day }}</div>
<div class="month-value">{{ entry.publication_date.month }}</div>
</div>
<div class="header-wrapper">
<h2 class="posttitle"><a href="single.html">{{entry.title}}</a></h2>
<div class="entry-utility">
<div class="user">Posted by <a href="#">Templatesquare</a></div> <div class="tag">Tags: <a href="#">Wordpress</a></div>
</div>
</div>
<div class="clear"></div>
<div class="postimg">
<img src="{{entry.head_image_url}}" alt="" />
</div>
<div class="entry-content">
{{ entry.blog_abstract }}
<a href="single.html" class="more">更多→</a>
</div>
<div class="clear"></div>
</article>
{% endfor %}
{% endif %}
<div class="wp-pagenavi">
<span class="step-links">
<span class="pages">
Page {{ latest_entry_list.number }} of {{ latest_entry_list.paginator.num_pages }}
</span>
{% if latest_entry_list.has_previous %}
<a href="?page={{ latest_entry_list.previous_page_number }}">{% trans 'previous' %}</a>
{% endif %}
{% for pagenum in latest_entry_list.paginator.page_range %}
{% if pagenum == latest_entry_list.number %}
<span class="current"><span>{{ pagenum }}</span></span>
{% else %}
<a class="page" href="?page={{ pagenum }}">{{ pagenum }}</a>
{% endif %}
{% endfor %}
{% if latest_entry_list.has_next %}
<a href="?page={{ latest_entry_list.next_page_number }}">{% trans 'next' %}</a>
{% endif %}
</span>
</div>
</section>
{% endblock %}
后台view代码
def blog(request):
latest_entry_list = Entry.objects.order_by('creation_date')
paginator = Paginator(latest_entry_list, 5)
page = request.GET.get('page')
try:
entrys = paginator.page(page)
except PageNotAnInteger:
entrys = paginator.page(1)
except EmptyPage:
entrys = paginator.page(paginator.num_pages)
context = {'latest_entry_list':entrys}
return render(request, 'blog.html', context)
这样分页就完成了。