分页介绍:
from django.core.paginator import Paginator
#这里的p是Paginator对象
p=paginator(XX,1)
#所有属性:
p.count#对象总数
p.num_pages#页面总数
p.page_range#基于1的页数范围迭代器。比如:[1, 2, 3, 4] 这个属性可以更简单的解决模板中不支持直接range()的问题
#这里的page是Page对象
page=p.page(1)
page=p.get_page(1)
#属性
Page.object_list:当前页上所有对象的列表。
Page.number:当前页的序号,从1开始计数。
Page.paginator:当前Page对象所属的Paginator对象
#方法
Page.has_next():如果有下一页,则返回True。
Page.has_previous():如果有上一页,返回 True。
Page.has_other_pages():如果有上一页或下一页,返回True。
Page.next_page_number():返回下一页的页码。如果下一页不存在,抛出InvalidPage异常。
Page.previous_page_number():返回上一页的页码。如果上一页不存在,抛出InvalidPage异常。
Page.start_index():返回当前页上的第一个对象,相对于分页列表的所有对象的序号,从1开始计数。 比如,将五个对象的列表分为每页两个对象,第二页的start_index()会返回3。
Page.end_index():返回当前页上的最后一个对象,相对于分页列表的所有对象的序号,从1开始。 比如,将五个对象的列表分为每页两个对象,第二页的end_index()会返回4。
举例说明:
>>> from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']
>>> p = Paginator(objects, 2) # 对objects进行分页,虽然objects只是个字符串列表,但没关系,一样用。每页显示2条。
>>> p.count # 对象个数
4
>>> p.num_pages # 总共几页
2
>>> type(p.page_range) # `<type 'rangeiterator'>` in Python 2.
<class 'range_iterator'>
>>> p.page_range # 分页范围
range(1, 3)
>>> page1 = p.page(1) # 获取第一页
>>> page1
<Page 1 of 2>
>>> page1.object_list # 获取第一页的对象
['john', 'paul']
>>> page2 = p.page(2)
>>> page2.object_list
['george', 'ringo']
>>> page2.has_next() # 判断是否有下一页
False
>>> page2.has_previous()# 判断是否有上一页
True
>>> page2.has_other_pages() # 判断是否有其它页
True
>>> page2.next_page_number() # 获取下一页的页码
Traceback (most recent call last):
...
EmptyPage: That page contains no results
>>> page2.previous_page_number() # 获取上一页的页码
1
>>> page2.start_index() # 从1开始计数的当前页的第一个对象
3
>>> page2.end_index() # 从1开始计数的当前页最后1个对象
4
>>> p.page(0) # 访问不存在的页面
Traceback (most recent call last):
...
EmptyPage: That page number is less than 1
>>> p.page(3) # 访问不存在的页面
Traceback (most recent call last):
...
EmptyPage: That page contains no results
要求:
- 对查询出来的数据进行分页处理
- 如果所有页码小于等于8,则展示所有页码
- 点击所有页码数字,跳转到对应页
方法1:自定义过滤器解决模板不支持range问题,完成对页码的迭代
修改views的内容
from django.core.paginator import Paginator
def article_list(request):
qry = ArticlePost.objects.all() #获取所有文章
#进行分页操作,每页2条数据
p = Paginator(qry,2)
##获取url中的页码,比如第一页,我们需要在url末尾中添加 ?page=1
page = request.GET.get('page')
##获取相应的页码的数据,比如page=1,第一页,这里获取得到第一页的数据内容
articles = p.get_page(page)
##获取一共分出来了多少页,前端展示所有页码数的时候需要用到该数
page_nums = p.num_pages
context={'articles':articles,'page_nums':page_nums}
return render(request,'article/list.html',context)
修改模板内容
<!--前面的文章的展示部分忽略,主要展示分页部分如何编写-->
<!--如果不是第一页,则展示'上一页'这个按钮-->
<!--如果该页有上一页 has_previous判断django.core.paginator.Page对象是否有上一页-->
{% if articles.has_previous %}
<!--Page对象.previous_page_number表示该页的上一页-->
<a href="?page={{articles.previous_page_number}}"> 上一页</a>
{% endif %}
<!--展示所有页码-->
<!--这里的demo设置为 如果页码小于8就全部展示,否则就只展示1-5...然后n-1,n 比如一共有100页,页码展示为 1 2 3 4 5 ... 99 100 -->
{% if page_nums <= 8 %}
<!--使用自定义过滤器,解决模板语言中不支持range()的问题 如何使用自定义模板参见:[https://www.cnblogs.com/alantammm/p/14303983.html]-->
{% for i in page_nums|get_range %}
{% if i == articles.number %}
<!--这里是高亮展示当前页,这里用了bootstrip,需要引入,这里先不用关注这点-->
<span class="current btn btn-danger btn-lg">
{{ articles.number }}
</span>
{% else %}
<!--其他页签就不用高亮展示了,但是点击其他页签的数据,会调到那一页去-->
<a href="?page={{ i }}">{{ i }}</a>
{% endif %}
{% endfor %}
{% else %}
<!--如果页数超过了8,就展示12345...n-1 n 页,中间用...展示-->
{% for i in 5|get_range %}
<!--高亮展示当前页 -->
{% if i == articles.number %}
<span class="current btn btn-danger btn-lg">
{{ articles.number }}
</span>
{% else %}
<!--其他页签就不用高亮展示了,但是点击其他页签的数据,会调到那一页去-->
<a href="?page={{ i }}">{{ i }}</a>
{% endif %}
{% endfor %}
<!--展示中间的...-->
...
<!--对最后的两个页码进行单独处理,处理逻辑同上-->
{% if page_nums|add:-1 == articles.number %}
<span class="current btn btn-danger btn-lg">
{{ articles.number }}
</span>
{% else %}
<a href="?page={{ page_nums|add:-1 }}">{{ page_nums|add:-1 }}</a>
{% endif %}
{% if page_nums == articles.number %}
<span class="current btn btn-danger btn-lg">
{{ articles.number }}
</span>
{% else %}
<a href="?page={{ page_nums }}">{{ page_nums }}</a>
{% endif %}
{% endif %}
<!--如果不是最后一页,则展示'下一页'这个按钮 has_next判断django.core.paginator.Page对象是否有下一页-->
{% if articles.has_next %}
<!--Page对象.next_page_number表示该页的上一页-->
<a href="?page={{articles.next_page_number}}"> 下一页</a>
{% endif %}
方法2:运用page_range返回基于1的页数范围迭代器的属性,来实现页码的迭代
所得到的效果如下: