Django自定义分页

Django自定义分页

  分页,就是分批次去数据库拿去数据并展示在前端。

  ORM中的简单的分页,在ORM操作中就可以定义:

models.UserInfo.object.all()[0:10]
models.UserInfo.object.all()[10:20]
models.UserInfo.object.all()[20:30]
#每次取10条数据

  在Django自带的分页做法流程:

url.py中做index.html 页面,views.index 。

在views中,写index函数。用paginator模块来实现分页。


#导入模块paginator
from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
def index(request):
    """
    分页
    """
  current_page = request.GET.get("page") #current_page表示取第几页,
  current_page = int(current_page) user_list
= models.UserInfo.objects.all()
  paginator = Paginator(user_list,10)
  #用paginator分页,两个参数,分别是要被分页的表的别名,和每页的显示数据。
  #per_page:每页显示的条目数量
  #count:数据总个数
  #num_pages:总页数
  #page_range:总页数的索引范围 如:(1:10),(100,200)
  #page:page对象
  #page的用法:
  #posts = paginator.page(1) #括号里加数字,显示第几页

  try:
    postss = paginator.page(current_page) #postss可以点出下列的内容
  except PageNotAnInteger as e:
    
postss = paginator.page(1)
  except EmptyPage as e:
    postss = paginator.page(1)

  #has_next:是否有下一页
  #next_page_number:下一页页码
  #has_previous:是否有上一页
  #previous_page_number:上一页页码
  #object_list:分页之后的数据列表
  #number:当前页
  #paginator:paginator对象

  
return render(request,"index.html",{"postss":postss})

精简后的index:

from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
def index(request):
    current_page = request.GET.get("page")
    user_list = models.UserInfo.objects.all()
    paginator = Paginator(user_list,10)
    try:
        posts = paginator.page(current_page)
    except PageNotAnInteger as e:
        posts = paginator.page(1)
    except EmptyPage as e:
        posts = paginator.page(1)
    
    return render(request,"index.html",{"posts":posts})

在template中写index.html页面


<html lang="en"> <head> <meta charset="utf-8"> <title></title> </head> <body> <h1>用户列表</h1> <u1> {% for item in postss.object_list % } <li>{{ item.name }}</li> {% endfor %} </u1>
  <div>
    {% if postss.has_previous %}
      <a href="/index.html?page={{ postss.previous_page_number }}">上一页</a>
    {% endif %}
    {% for num in postss.paginator.page_range %}
      <a href="/index.html?page={{num}}">{{num}}</a>
    {% endfor %}    

    {% if postss.has_next %}
      <a href="/index.html?page={{ postss.next_page_number }}">下一页</a>
    {% endif %}
  </div> </body> </html>

django自带的分页有不好的地方,就是他不能将页数部分显示,部分隐藏。它只能全部都显示出来,如果数据量大,页数多,那么在前端的展示就会不友好。所以要二次开发。

-------自行开发的分页--------

 

#要导入bootstrap
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: 每页显示个数
        :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:
            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):
        # v = "<a href='/custom.html?page=1'>1</a><a href='/custom.html?page=2'>2</a>"
        # return v
        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>"
        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:
                #class标签是将当前页加标志色
                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)

  custom页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" />
</head>
<body>
    <h1>用户列表</h1>
    <ul>
        {% for row in user_list %}
            <li>{{ row.name }}</li>
        {% endfor %}
    </ul>

    <nav aria-label="Page navigation">
      <ul class="pagination">
          {{ page_info.pager|safe }}
      </ul>
    </nav>
</body>
</html>

views:

from utils.pager import PageInfo
def custom(request):
    # 表示用户当前想要访问的页码: 8

    all_count = models.UserInfo.objects.all().count()

    page_info = PageInfo(request.GET.get('page'),all_count,10,'/custom.html',11)
    user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()]

    return render(request,'custom.html',{'user_list':user_list,'page_info':page_info})

全部views:

  1 from django.shortcuts import render,HttpResponse
  2 from app01 import models
  3 from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
  4 def test(request):
  5     # 创建数据
  6     # models.UserType.objects.create(title='普通用户')
  7     # models.UserType.objects.create(title='二逼用户')
  8     # models.UserType.objects.create(title='牛逼用户')
  9 
 10     # models.UserInfo.objects.create(name='方少伟',age=18,ut_id=1)
 11     # models.UserInfo.objects.create(name='由秦兵',age=18,ut_id=2)
 12     # models.UserInfo.objects.create(name='刘庚',age=18,ut_id=2)
 13     # models.UserInfo.objects.create(name='陈涛',age=18,ut_id=3)
 14     # models.UserInfo.objects.create(name='王者',age=18,ut_id=3)
 15     # models.UserInfo.objects.create(name='杨涵',age=18,ut_id=1)
 16 
 17     # 获取
 18     # QuerySet[obj,obj,obj]
 19     # result = models.UserInfo.objects.all()
 20     # for obj in result:
 21     #     print(obj.name,obj.age,obj.ut_id,obj.ut.title)
 22 
 23     # UserInfo,ut是FK字段 - 正向操作  PS: 一个用户只有一个用户类型
 24     # obj = models.UserInfo.objects.all().first()
 25     # print(obj.name,obj.age,obj.ut.title)
 26 
 27     # UserType, 表名小写_set.all()  - 反向操作   PS: 一个用户类型下可以有很多用户
 28     # obj = models.UserType.objects.all().first()
 29     # print('用户类型',obj.id,obj.title)
 30     # for row in obj.userinfo_set.all():
 31     #     print(row.name,row.age)
 32 
 33     # result = models.UserType.objects.all()
 34     # for item in result:
 35     #     print(item.title,item.userinfo_set.filter(name='xx'))
 36 
 37     # obj
 38     # [obj,obj,]
 39 
 40     # result = models.UserInfo.objects.all().values('id','name')
 41     # QuerySet[{'id':'xx','name':'xx'} ]
 42     # for row in result:
 43     #     print(row)
 44 
 45     # result = models.UserInfo.objects.all().values_list('id','name')
 46     # QuerySet[(1,'f'), ]
 47     # for row in result:
 48     #     print(row)
 49 
 50     # 数据获取多个数据时
 51     # 1. [obj,obj,obj,]
 52     # models.UserInfo.objects.all()
 53     # models.UserInfo.objects.filter(id__gt=1)
 54     # result = models.UserInfo.objects.all()
 55     # for item in result:
 56     #     print(item.name,item.ut.title)
 57 
 58     # 2. [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},]
 59     # models.UserInfo.objects.all().values('id','name')
 60     # models.UserInfo.objects.filter(id__gt=1).values('id','name')
 61     # 无法跨表
 62     # result = models.UserInfo.objects.all().values('id','name')
 63     # for item in result:
 64     #     print(item['id'],item['name'])
 65     # 夸表  __
 66     # result = models.UserInfo.objects.all().values('id','name',"ut__title")
 67     # for item in result:
 68     #     print(item['id'],item['name'],item['ut__title'])
 69 
 70 
 71     # 3. [(1,df),(2,'df')]
 72     # models.UserInfo.objects.all().values_list('id','name')
 73     # models.UserInfo.objects.filter(id__gt=1).values_list('id','name')
 74     # 无法跨表
 75     # result = models.UserInfo.objects.all().values_list('id','name')
 76     # for item in result:
 77     #     print(item[0],item[1])
 78     # 夸表  __
 79     # result = models.UserInfo.objects.all().values_list('id','name',"ut__title")
 80     # for item in result:
 81     #     print(item[0],item[1],item[2])
 82 
 83 
 84 
 85 
 86 
 87 
 88 
 89     return HttpResponse('...')
 90 
 91 from django.views import View
 92 class Login(View):
 93     """
 94     get     查
 95     post    创建
 96     put     更新
 97     delete  删除
 98     """
 99     def dispatch(self, request, *args, **kwargs):
100         print('before')
101         obj = super(Login,self).dispatch(request, *args, **kwargs)
102         print('after')
103         return obj
104 
105     def get(self,request):
106         # return HttpResponse('Login.get')
107         return render(request,'login.html')
108 
109     def post(self,request):
110         print(request.POST.get('user'))
111         return HttpResponse('Login.post')
112 
113 
114 
115 
116 def index(request):
117     """
118     分页
119     :param request:
120     :return:
121     """
122     # for i in range(300):
123     #     name = "root" + str(i)
124     #     models.UserInfo.objects.create(name=name,age=18,ut_id=1)
125 
126 
127     current_page = request.GET.get('page')
128 
129     user_list = models.UserInfo.objects.all()
130     paginator = Paginator(user_list,10)
131     # per_page: 每页显示条目数量
132     # count:    数据总个数
133     # num_pages:总页数
134     # page_range:总页数的索引范围,如: (1,10),(1,200)
135     # page:     page对象
136     try:
137         posts = paginator.page(current_page)
138     except PageNotAnInteger as e:
139         posts = paginator.page(1)
140     except EmptyPage as e:
141         posts = paginator.page(1)
142     # has_next              是否有下一页
143     # next_page_number      下一页页码
144     # has_previous          是否有上一页
145     # previous_page_number  上一页页码
146     # object_list           分页之后的数据列表
147     # number                当前页
148     # paginator             paginator对象
149     return render(request,'index.html',{'posts':posts})
150 
151 from utils.pager import PageInfo
152 def custom(request):
153     # 表示用户当前想要访问的页码: 8
154 
155     all_count = models.UserInfo.objects.all().count()
156 
157     page_info = PageInfo(request.GET.get('page'),all_count,10,'/custom.html',11)
158     user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()]
159 
160     return render(request,'custom.html',{'user_list':user_list,'page_info':page_info})
全部views

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

原文地址:https://www.cnblogs.com/george92/p/10167082.html