分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户的输入计算出应该显示在页面上的数据在数据库表中的起始位置。
确定分页需求:
1. 每页显示的数据条数
2. 每页显示页号链接数
3. 上一页和下一页
4. 首页和末页
效果图:
首先,利用django内置的分页功能,写分页类:
1 from django.core.paginator import Paginator, Page # 导入django分页模块
2
3
4 class PageInfo(object):
5 def __init__(self, current_page, all_count, base_url, per_page=10, show_page=11):
6 """
7
8 :param current_page: 当前页
9 :param all_count: 总页数
10 :param base_url: 模板
11 :param per_page: 每页显示数据条数
12 :param show_page: 显示链接页个数
13 """
14 #若url错误,默认显示第一页(错误类型可能为:空页面编号,非整数型页面编号)
15 try:
16 self.current_page = int(current_page)
17 except Exception as e:
18 self.current_page = 1
19
20 #根据数据库信息条数得出总页数
21 a, b = divmod(all_count, per_page)
22 if b:
23 a += 1
24 self.all_page = a
25
26 self.base_url = base_url
27 self.per_page = per_page
28 self.show_page = show_page
29
30 #当前页起始数据id
31 def start_data(self):
32 return (self.current_page - 1) * self.per_page
33
34 #当前页结束数据id
35 def end_data(self):
36 return self.current_page * self.per_page
37
38 #动态生成前端html
39 def pager(self):
40 page_list = []
41 half = int((self.show_page - 1)/2)
42 #如果:总页数 < show_page,默认显示页数范围为: 1~总页数
43 if self.all_page < self.show_page:
44 start_page = 1
45 end_page = self.all_page + 1
46 #如果:总页数 > show_page
47 else:
48 #如果:current_page - half <= 0,默认显示页数范围为:1~show_page
49 if self.current_page <= half:
50 start_page = 1
51 end_page = self.show_page + 1
52 else:
53 #如果:current_page + half >总页数,默认显示页数范围为:总页数 - show_page ~ 总页数
54 if self.current_page + half > self.all_page:
55 end_page = self.all_page + 1
56 start_page = end_page - self.show_page
57 else:
58 start_page = self.current_page - half
59 end_page = self.current_page + half + 1
60
61 #首页
62 first_page = "<li><a href='%s?page=%s'>首页</a></li>" %(self.base_url, 1)
63 page_list.append(first_page)
64
65 #上一页(若当前页等于第一页,则上一页无链接,否则链接为当前页减1)
66 if self.current_page <= 1:
67 prev_page = "<li><a href='#'>上一页</a></li>"
68 else:
69 prev_page = "<li><a href='%s?page=%s'>上一页</a></li>" %(self.base_url, self.current_page-1)
70 page_list.append(prev_page)
71
72 #动态生成中间页数链接
73 for i in range(start_page, end_page):
74 if i == self.current_page:
75 temp = "<li class='active'><a href='%s?page=%s'>%s</a></li>" %(self.base_url, i, i)
76 else:
77 temp = "<li><a href='%s?page=%s'>%s</a></li>" % (self.base_url, i, i)
78 page_list.append(temp)
79
80 #下一页(若当前页等于最后页,则下一页无链接,否则链接为当前页加1)
81 if self.current_page >= self.all_page:
82 next_page = "<li><a href='#'>下一页</a></li>"
83 else:
84 next_page = "<li><a href='%s?page=%s'>下一页</a></li>" %(self.base_url, self.current_page+1)
85 page_list.append(next_page)
86
87 #末页(若总页数只有一页,则无末页标签)
88 if self.all_page > 1:
89 last_page = "<li><a href='%s?page=%s'>末页</a></li>" % (self.base_url, self.all_page)
90 page_list.append(last_page)
91
92 return ''.join(page_list)
然后,在views中写方法(此处写在app01中):
1 from utils.pagnition import PageInfo # 从文件中导入上步自定义的分页模块
2
3 def custom(request):
4 all_count = models.UserInfo.objects.all().count() # 获取要显示数据库的总数据条数
5 page_info = PageInfo(request.GET.get('page'), all_count, '/custom.html/',) # 生成分页对象
6 user_list = models.UserInfo.objects.all()[page_info.start_data():page_info.end_data()] # 利用分页对象获取当前页显示数据
7 return render(request, 'custom.html', {'user_list': user_list, 'page_info': page_info}) # 模板渲染
然后,在templates目录下写“custom.html"文件:
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>customers</title>
6 {# 引入bootstrap样式#}
7 <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
8 </head>
9 <body>
10 <h1>customers</h1>
11 {#当前页显示的数据#}
12 <ul>
13 {% for row in user_list %}
14 <li>{{ row.name }}</li>
15 {% endfor %}
16 </ul>
17
18 {#分页#}
19 <nav aria-label="Page navigation">
20 <ul class="pagination">
21 {# 传入page_info.pager#}
22 {{ page_info.pager|safe }}
23 </ul>
24 </nav>
25
26 </body>
27 </html>
最后,新增url关系(urls.py):
1 from django.conf.urls import url
2 from django.contrib import admin
3 from app01 import views as app01_views
4
5 urlpatterns = [
6 url(r'^custom.html/$', app01_views.custom),
7 ]
至此,就完成了利用django的分页功能自定义分页模块,可以应用在不同的业务页面上。
参考资料: