Django本身提供简单的分类功能,但不够漂亮,要如何将分页功能实现得漂亮一点呢。这里用的bottstrap进行快速样式处理。
这里主要是考虑当页数太多时,需要将一部分页码隐藏起来,但如果页码较少,隐藏是完全没必要的,所以我们以页码大于7为界。
1.总页码少于7,全部显示
2.总页码大于7:
如:1 2 3 4 5 6 7 8
2.1 当前页码大于等于7(当前页码-5大于1),前面页码都有隐藏,左侧显示4,5,6(当,当前为6时因为只有2一个页码,无需省略)
此时取页码为:page_range[current_page - 4:current_page - 1]
2.2 此时判断右侧页码,当前页码+5 小于最后一个页码,需要隐藏,否则没必要。
此时取页码为:page_range[current_page - 1:current_page + 2] + [last_page_num,]
2.3 其它情况下直接从当前页码取到第一页或者最后一页。
下面看代码:paginate_tags.py
#!usr/bin/env python
# *- coding:utf-8 -*-
# Andy Create @ 7/20/2019 9:48 AM
from django import template
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
register = template.Library()
@register.simple_tag(takes_context=True)
def paginate(context, object_list, page_count):
# page_count ·每页显示的文章数量
# left_dot 左边是否显示省略号 right_dot same
# page_num 当前请求的页码 == current_page
# object_page_list 当前请求页的对象
#
paginator = Paginator(object_list, page_count)
page_num = context['request'].GET.get('page', 1)
try:
page_num = page_num
except PageNotAnInteger:
page_num = 1
except EmptyPage:
page_num = paginator.num_pages
def get_pages(paginator, page_num, left_dot=False, right_dot=False):
current_page = int(page_num)
context['current_page'] = current_page
page_range = list(paginator.page_range)
first_page_num = page_range[0]
last_page_num = page_range[-1]
if page_range[-1] <= 7:
pages = list(page_range)
else:
# 获取当前页面右侧页码
if current_page + 5 < last_page_num:
right_dot = True
right_pages = page_range[current_page - 1:current_page + 2] + [last_page_num, ] # include current page
else:
right_pages = page_range[current_page - 1:] # include current page
# 获取当前页面左侧页码
if current_page - 5 > first_page_num:
left_dot = True
left_pages = [first_page_num, ] + page_range[current_page - 4:current_page - 1]
else:
left_pages = page_range[:current_page - 1]
pages = left_pages + right_pages
pages = pages[1:-1]
return pages, right_dot, left_dot
context['current_page'] = page_num
pages, right_dot, left_dot = get_pages(paginator, page_num)
object_page_list = paginator.page(page_num)
context['article_list'] = object_page_list
context['pages'] = pages
context['last_page'] = paginator.num_pages
context['first_page'] = 1
context['left_dot'] = left_dot
context['right_dot'] = right_dot
最终显示效果为:
上面的样式是用的bootstrap.
html代码如下:
<nav aria-label="...">
<ul class="pagination">
{% if article_list.has_previous %}
<li><a class="previous-page" href="?page={{ article_list.previous_page_number }}">
上一页
</a></li>
{% endif %}
{% if first_page == current_page %}
<li class="active"><a href="?page=1">1</a></li>
{% else %}
<li><a href="?page=1" class="first-page">1</a></li>
{% endif %}
{% if left_dot %}
<li><span>...</span></li>
{% endif %}
{% for page in pages %}
{% if page == current_page %}
<li class="active"><span class="current">{{ page }}</span></li>
{% else %}
<li><a href="?page={{ page }}">{{ page }}</a></li>
{% endif %}
{% endfor %}
{% if right_dot %}
<li><span>...</span></li>
{% endif %}
{% if last_page != 1 %}
{% if last_page == current_page %}
<li class="active"><span>{{ last_page }}</span></li>
{% else %}
<li><a href="?page={{ last_page }}">{{ last_page }}</a></li>
{% endif %}
{% endif %}
{% if article_list.has_next %}
<li><a class="next-page" href="?page={{ article_list.next_page_number }}">下一页</a></li>
{% endif %}
</ul>
</nav>
在主页面引入这个标签:(后面的数字7表示每页显示7条博客,可以通过view函数 中的context传入。
{% paginate article_list 7 %}
在博客内容后面引入 这个页码:
<div class="text-center">
{% include 'pages.html' %}
</div>