一、目的
因为往往数据库中的数据在前端页面展示出来一页肯定是不够的,而一个网页的容量就那么大,所以肯定要分页显示。
二、实施
其实仔细想想,如果数据量小的话,直接在后台的views处理函数中分批的去获取数据就可以,比如:
1
2
|
models.UserInfo.objects.
all
()[
0
:
10
]
#UserInfo代表数据表,[0:10]表示获取第一个到第十个数据
models.UserInfo.objects.
all
()[
0
:
10
]
#同上
|
django中自带分页功能,需要导入Paginator模块,如下:
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
|
from
django.core.paginator
import
Paginator,Page
cur_page
=
request.GET.get(
'page'
)
#获取用户请求中的当前页码,示例使用url--GET传值
#http://127.0.0.1:8000/index.html/?page=1
user_list
=
models.UserInfo.objects.
all
()
paginator
=
Paginator(user_list,
10
)
'''
这个paginator对象中带有如下属性:
#per_page:每页显示条目数量
#count:数据总个数
#num_pages:总页数
#page_range:总页数的索引范围,如:(1,10),(1,200)
#page:page对象
'''
posts
=
paginator.page(cur_page)
#如果当前页不是数字或者页码是负数的话在此加try...except
'''
# has_next 是否有下一页
# next_page_number 下一页页码
# has_previous 是否有上一页
# previous_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator paginator对象
'''
return
render(request,
'index.html'
,{
'posts'
:posts}
#将posts传到模板进行渲染返回页面
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#模板代码如下:
<
ul
>
{% for row in posts.object_list %} #通过posts的object_list属性获取所有的数据行
<
li
>{{ row.name }}</
li
>
{% endfor %}
</
ul
>
<
div
>
{% if posts.has_previous %} #判断如果posts对象有上一页则渲染上一页
<
a
href
=
"/index.html?page={{ posts.previous_page_number }}"
>上一页</
a
>
{% endif %}
{% for num in posts.paginator.page_range %}
<
a
href
=
"/index.html/?page={{ num }}"
>{{ num }}</
a
>
{% endfor %}
{% if posts.has_next %} #判断下一页
<
a
href
=
"/index.html?page={{ posts.next_page_number }}"
>下一页</
a
>
{% endif %}
</
div
>
|
注:上述django自带的分页功能会将所有页码全部显示,是有一定的局限性的,只适合有上一页下一页的网页,如果需要显示限定数目的页码的话就需要自己定制了,而且此种方法也只能在django框架中用,换作其他框架也不行。
三、自定义分页功能
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#分页模块,封装成类,以后直接使用即可
class
PageInfo(
object
):
def
__init__(
self
,current_page,all_count,per_page,base_url,show_page
=
11
):
"""
:param current_page:当前页
:param all_count: 数据库总行数
:param per_page: 每页显示函数
:base_url:url前缀
:show_page:
:return:
"""
try
:
self
.current_page
=
int
(current_page)
#如果页码不合理跳转到第一页
except
Exception as e:
self
.current_page
=
1
self
.per_page
=
per_page
a,b
=
divmod
(all_count,per_page)
#通过数据库数据总条数和每页显示的数据条数获取
if
b:
#总页数(余数不为0总页数多显示1页)
a
=
a
+
1
self
.all_pager
=
a
self
.show_page
=
show_page
self
.base_url
=
base_url
def
start(
self
):
#数据起始位置
return
(
self
.current_page
-
1
)
*
self
.per_page
def
end(
self
):
#数据结束位置
return
self
.current_page
*
self
.per_page
def
pager(
self
):
page_list
=
[]
#用于在模板中渲染所要显示的页码
half
=
int
((
self
.show_page
-
1
)
/
2
)
# 如果数据总页数 < 11 需要显示全部页码
if
self
.all_pager <
self
.show_page:
begin
=
1
stop
=
self
.all_pager
+
1
# 如果数据总页数 > 11
else
:
# 如果当前页 <=5,永远显示1,11
if
self
.current_page <
=
half:
begin
=
1
stop
=
self
.show_page
+
1
else
:
if
self
.current_page
+
half >
self
.all_pager:
begin
=
self
.all_pager
-
self
.show_page
+
1
stop
=
self
.all_pager
+
1
else
:
begin
=
self
.current_page
-
half
stop
=
self
.current_page
+
half
+
1
if
self
.current_page <
=
1
:
prev
=
"<li><a href='#'>上一页</a></li>"
#当前页为
1
则上一页点击不跳转
else
:
prev
=
"<li><a href='%s?page=%s'>上一页</a></li>"
%
(
self
.base_url,
self
.current_page
-
1
,)
page_list.append(prev)
#先将上一页标签添加到需要渲染的页码列表
for
i
in
range
(begin,stop):
if
i
=
=
self
.current_page:
#引入bootstrap,给选中页码加样式
temp
=
"<li class='active'><a href='%s?page=%s'>%s</a></li>"
%
(
self
.base_url,i,i,)
else
:
temp
=
"<li><a href='%s?page=%s'>%s</a></li>"
%
(
self
.base_url,i,i,)
page_list.append(temp)
if
self
.current_page >
=
self
.all_pager:
#将下一页添加在页码最后
nex
=
"<li><a href='#'>下一页</a></li>"
else
:
nex
=
"<li><a href='%s?page=%s'>下一页</a></li>"
%
(
self
.base_url,
self
.current_page
+
1
,)
page_list.append(nex)
return
''.join(page_list)
#将页码标签列表拼接成字符串返回
|
分页时需要做的三件事:
1、创建处理分页数据的类
2、根据分页数据获取数据
3、输出分页HTML并且适当的加一些样式
本文转自 AltBoy 51CTO博客,原文链接:http://blog.51cto.com/altboy/1942124