django 分页组件
Posted zjltt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django 分页组件相关的知识,希望对你有一定的参考价值。
一、仿django分页功能自己实现
urls.py
1
2
3
4
5
6
7
8
9
|
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^index.html$\', views.index), ] |
views.py
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
|
from django.shortcuts import render from app01 import models # Create your views here. USER_LIST = [] #创建数据999条 for i in range(999): temp = {\'name\':\'root\'+str(i),\'age\':i } #加到userlist列表中 USER_LIST.append(temp) def index(request): #每页显示10条数据 per_page_count = 10 #current-page 当有页 current_page = request.GET.get(\'p\') #数字运算要转成int类型 current_page = int(current_page) #如果是第1页,索引0-9,就是1-10的数 #p=1 #0,10 0-9 取索引 #p=2 #大于等于10,小于20就是10-19 #10,20 10-19 #start 开始页数 end=结束页数 #如果p=1-1=0 start = (current_page - 1) * per_page_count #1 * 10=10 end = current_page*per_page_count #数据切片,每次显示10页 data = USER_LIST[start:end] #上一页 prev_pager = current_page -1 #下一页 next_pager = current_page +1 return render(request,\'index.html\',{\'user_list\':data,\'prev_pager\':prev_pager,\'next_pager\':next_pager }) |
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >Title</ title > </ head > < body > < ul > {% for row in user_list %} < li >{{ row.name }}-{{ row.age }}</ li > {% endfor %} </ ul > < a href="/index.html?p={{ prev_pager }}">上一页</ a > < a href="/index.html?p={{ next_pager }}">下一页</ a > </ body > </ html > |
二、利用django自带分页组件实现分页功能
使用分页器Paginator:
在视图中使用 Paginator来为查询集分页。我们提供视图以及相关的模板来展示如何展示这些结果。
1
2
3
4
5
|
Paginator常用属性 per_page: 每页显示条目数量 count: 数据总个数 num_pages:总页数 page_range:总页数的索引范围,页码的范围,从1开始,例如[1, 2, 3, 4]。 |
Paginator所需参数:
1
2
|
object_list 一个列表,元祖或则Django 的Queryset 对象 或则其他对象带有 count() or __len__()的方法 per_page :就是1页显示几条数据 |
Paginator对象的方法:
1
|
page(number) :返回在提供的下标处的Page对象,下标以1开始。 |
使用page对象方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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。 |
属性
1
2
3
4
5
6
7
8
|
Page.object_list 当前页上所有对象的列表。 Page.number 当前页的序号,从1开始。 Page.paginator 相关的Paginator对象。 |
代码示例:
Django内置分页:Paginator、Page
urls.py
1
2
3
4
5
6
7
8
9
|
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), # url(r\'^index.html$\', views.index), url(r\'^index1.html$\', views.index1), ] |
views.py
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
|
from django.shortcuts import render from django.shortcuts import redirect from django.shortcuts import HttpResponse from app01 import models # Create your views here. USER_LIST = [] #创建数据999条 for i in range(999): temp = {\'name\':\'root\'+str(i),\'age\':i } #加到userlist列表中 USER_LIST.append(temp) def index1(request): from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger #全部数据:USER_LIST,=>得出共有多少条数据 # per_page: 每页显示条目数量 # count: 数据总个数 # num_pages:总页数 # page_range:总页数的索引范围,如: (1,10),(1,200) # page: page对象 (是否具有下一页,是否有上一页) current_page = request.GET.get(\'p\') #Paginator对象,里面封装了上面那些值,把USER_LIST对象传过来了,显示10页 paginator = Paginator(USER_LIST,10) try: #page对象 #posts配置对象(current_page用户可能填些不合法的字段) #paginator通过拿到了page对象,把current_page传进来 posts = paginator.page(current_page) # has_next 是否有下一页 # next_page_number 下一页页码 # has_previous 是否有上一页 # previous_page_number 上一页页码 # object_list 分页之后的数据列表,已经切片好的数据 # number 当前页 # paginator paginator对象 #表示你填的东西不是个整数 except PageNotAnInteger: posts = paginator.page(1) #空页的时候,表示你看完了,显示最后一页 except EmptyPage: posts = paginator.page(paginator.num_pages) return render(request,\'index1.html\' ,{\'posts\':posts}) |
index1.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >Title</ title > </ head > < body > < ul > {% for row in posts.object_list %} < li >{{ row.name }}-{{ row.age }}</ li > {% endfor %} </ ul > {% include \'include/pager.html\' %} </ body > </ html > |
pager.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
{% if posts.has_previous %} < a href="/index1.html?p={{ posts.previous_page_number }}">上一页</ a > {% else %} < a href="#">上一页</ a > {% endif %} {% if posts.has_next %} < a href="/index1.html?p={{ posts.next_page_number }}">下一页</ a > {% endif %} < span > {{ posts.number }} / {{ posts.paginator.num_pages }} </ span > {#切片完后,就叫object_list#} |
三、扩展Django内置分页
urls.py
1
2
3
4
5
6
7
|
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^index/$\', views.listing), ] |
views.py
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
|
from django.shortcuts import render from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger # Create your views here. #模拟测试网页数据 USER_LIST = [] for i in range(1,999): temp = {"name":"root"+str(i),"age":i} USER_LIST.append(temp) class CustomPaginator(Paginator): def __init__(self,current_page,per_pager_num,*args,**kwargs): # per_pager_num 显示的页码数量 self.current_page = int(current_page) self.per_pager_num = int(per_pager_num) super(CustomPaginator,self).__init__(*args,**kwargs) def pager_num_range(self): \'\'\' 自定义显示页码数 第一种:总页数小于显示的页码数 第二种:总页数大于显示页数 根据当前页做判断 a 如果当前页大于显示页一半的时候 ,往右移一下 b 如果当前页小于显示页的一半的时候,显示当前的页码数量 第三种:当前页大于总页数 :return: \'\'\' if self.num_pages < self.per_pager_num: return range(1,self.num_pages+1) half_part = int(self.per_pager_num/2) if self.current_page <= half_part: return range(1,self.per_pager_num+1) if (self.current_page+half_part) > self.num_pages: return range(self.num_pages-self.per_pager_num+1,self.num_pages) return range(self.current_page-half_part,self.current_page+half_part+1) def listing(request): current_page = request.GET.get(\'p\') paginator = CustomPaginator(current_page,11,USER_LIST,10) try: paginator = paginator.page(current_page) #获取前端传过来显示当前页的数据 except PageNotAnInteger: # 如果有异常则显示第一页 paginator = paginator.page(1) except EmptyPage: # 如果没有得到具体的分页内容的话,则显示最后一页 paginator = paginator.page(paginator.num_pages) return render(request,\'index.html\',{"users":paginator}) |
index.html
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
|
<! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >Title</ title > </ head > < body > < ul > {% for user in users.object_list %} < li >{{ user.name }}-{{ user.age }}</ li > {% endfor %} {% if users.has_previous %} < a href="/index?p={{ users.previous_page_number }}">上一页</ a > {% endif %} {% for number in users.paginator.pager_num_range %} {% if number == users.number %} < a href="/index?p={{ number }}" style="font-size: 33px">{{ number }}</ a > {% else %} < a href="/index?p={{ number }}" >{{ number }}</ a > {% endif %} {% endfor %} {% if users.has_next %} < a href="/index?p={{ users.next_page_number }}">下一页</ a > {% endif %} < span >{{ users.number }} /{{ users.paginator.num_pages }}</ span > </ ul > </ body > </ html > |
没加特效:
二、自定义分页器
效果:
分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户的输入计算出应该在数据库表中的起始位置。
1
2
3
4
5
6
7
|
1、设定每页显示数据条数 2、用户输入页码(第一页、第二页...) 3、根据设定的每页显示条数和当前页码,计算出需要取数据表的起始位置 4、在数据表中根据起始位置取值,页面上输出数据 |
需求,需要在页面上显示分页
以上是关于django 分页组件的主要内容,如果未能解决你的问题,请参考以下文章