ORM之自定义分页

ORM之自定义分页

  分页是为了在前端展示的时候,数据量过多,导致读取是不方便的问题。

  所有我们来实现一下django的分页,并把它写成一个可以在任意django项目中都可用的一个小插件。

  分页,其实就是分批次获取数据。

  在ORM中获取全部数据后分批次显示数据就是:

models.UserInfo.object.all()[0:10]   #取0到10索引值的数据
models.UserInfo.object.all()[10:20]   #取10到20索引值的数据

  Django自有的分页样例:需要导入 from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage

  url中的index

url(r'^index/',views.index)

  在view中的index:

 1 def index(request):
 2     """
 3     分页
 4     :param request:
 5     :return:
 6     """
 7     from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
 8     # for i in range(300):
 9     #     name = "george" + str(i)
10     #     models.UserInfo.objects.create(name=name,age=18,ut_id=1)
11     #这端for循环用一次生成数据即可
12 
13     current_page = request.GET.get("page") #取第几页
14     user_list = models.UserInfo.objects.all()
15     paginator = Paginator(user_list,10)
16     #参数的意义,user_list是要分页的数据,10是一页显示的数据量
17     #per_page:每页显示条目数量
18     #count:数据总个数
19     #num_pages:总页数
20     #page_range:总页数的索引范围,如:(1,10),(1,200)
21     #page:page对象
22     try:
23         posts = paginator.page(current_page) #当前显示第几页
24         #has_next: 是否有下一页
25         #next_page_number:下一页页码
26         #has_previous:是否有上一页
27         #previous_page_number:上一页页码
28         #object_list:分页之后的数据列表
29         #number:当前页
30         #paginator:paginator对象
31     except PageNotAnInteger as e:
32         posts = paginator.page(1)
33     except EmptyPage as e:
34         posts = paginator.page(1)
35     return render(request,"index.html",{"posts":posts})
View Code

  在前端的html:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>index</title>
 6 </head>
 7 <body>
 8     <h1>用户列表</h1>
 9     <ul>
10         {% for row in posts.object_list %}
11             <li>{{ row.name }}</li>
12         {% endfor %}
13     </ul>
14     <div>
15         {% if posts.hax_next %}
16             <a href="/index/?page={{ posts.previous_page_number }}">上一页</a>
17         {% endif %}
18         
19         {% for num in posts.paginator.page_range %}
20             <a href="/index/?page={{ num }}">{{ num }}</a>
21         {% endfor %}
22     
23         {% if posts.hax_next %}
24             <a href="/index/?page={{ posts.next_page_number }}">下一页</a>
25         {% endif %}
26     </div>
27 </body>
28 </html>
View Code

  django 的自带分页的弊端是只有上下页可以方便的直接使用,但是如果要显示页码的话,django是全部显示的,这要如果数据量大的话,全端会极其不美观,也不便利,但是如果想让其有固定的页面显示长度,就需要二次开发。 

  Django自定义分页:

  url的custom:

url(r'^custom/',views.custom)

  在前端的展示样例:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" />
 7 </head>
 8 <body>
 9     <h1>用户列表</h1>
10     <ul>
11         {% for row in user_list %}
12             <li>{{ row.name }}</li>
13         {% endfor %}
14     </ul>
15 
16     <nav aria-label="Page navigation">
17       <ul class="pagination">
18           {{ page_info.pager|safe }}
19       </ul>
20     </nav>
21 </body>
22 </html>
View Code

  最为关键的,创建一个utils包,作为模块使用,文件名为pager.py 

 1 class PageInfo(object):
 2 
 3     def __init__(self,current_page,all_count,per_page,base_url,show_page=11):
 4         """
 5         :param current_page: 表示用户当期想要访问的页码
 6         :param all_count: 数据库总行数
 7         :param per_page: 每页显示个数
 8         :param base_url: 每页显示个数
 9         :param show_page: 总共显示多少页码
10         :return:
11         """
12         try:
13             # 异常处理,页码出现非数字的,返回第一页
14             self.current_page = int(current_page)
15         except Exception as e:
16             # 返回第一页
17             self.current_page = 1
18 
19         # 每页显示的个数
20         self.per_page = per_page
21 
22         #计算需要的页数,总数据行和每页显示的个数做比例
23         a,b = divmod(all_count,per_page)
24         if b:
25             a = a +1
26         self.all_pager = a
27         self.show_page = show_page
28         self.base_url = base_url
29     def start(self):
30         #每页的起始的数据行
31         return (self.current_page-1) * self.per_page
32 
33     def end(self):
34         #每页的结束数据行
35         return self.current_page * self.per_page
36 
37     def pager(self):
38         # v = "<a href='/custom.html?page=1'>1</a><a href='/custom.html?page=2'>2</a>"
39         # return v
40         page_list = []
41 
42         #在页码中取一半
43         half = int((self.show_page-1)/2)
44 
45         # 如果数据总页数 < 11
46         if self.all_pager < self.show_page:
47             begin = 1
48             stop = self.all_pager + 1
49         # 如果数据总页数 > 11
50         else:
51             # 如果当前页 <=5,永远显示1,11
52             if self.current_page <= half:
53                 begin = 1
54                 stop = self.show_page + 1
55             else:
56                 if self.current_page + half > self.all_pager:
57                     begin = self.all_pager - self.show_page + 1
58                     stop = self.all_pager + 1
59                 else:
60                     begin = self.current_page - half
61                     stop = self.current_page + half + 1
62 
63         if self.current_page <= 1:
64             prev = "<li><a href='#'>上一页</a></li>"
65         else:
66             prev = "<li><a href='%s?page=%s'>上一页</a></li>" %(self.base_url,self.current_page-1,)
67         page_list.append(prev)
68 
69         for i in range(begin,stop):
70             if i == self.current_page:
71                 #class标签是将当前页加标志色
72                 temp = "<li class='active'><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)
73             else:
74                 temp = "<li><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)
75             page_list.append(temp)
76 
77         if self.current_page >= self.all_pager:
78             nex = "<li><a href='#'>下一页</a></li>"
79         else:
80             nex = "<li><a href='%s?page=%s'>下一页</a></li>" %(self.base_url,self.current_page+1,)
81         page_list.append(nex)
82 
83         return ''.join(page_list)
View Code 

  在views中代码实现:在custom函数中,就可以from导入utils模块的pager文件的PageInfole类,直接用,给PageInfo传参即可。

 1 from utils.pager import PageInfo
 2 def custom(request):
 3     #总数据的个数
 4     all_count = models.UserInfo.objects.all().count()
 5     #表示用户当期想要访问的页码
 6     current_page = request.GET.get("page")
 7     # current_page = int(current_page)
 8     #每页显示数据个数
 9     # per_page = 10
10     # start = (current_page-1) * per_page
11     # end = current_page * per_page
12     page_info = PageInfo(current_page,all_count,10,"/index/",11)
13     # models.UserInfo.objects.all()[起始位置:结束位置]
14     user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()]
15 
16     return render(request,"index.html",{"user_list":user_list,'page_info':page_info})
View Code

 

------------- END -------------

 

posted @ 2019-07-31 18:44  王先生是胖子  阅读(286)  评论(0编辑  收藏  举报