Django-分页 Python之路【第十七篇】:Django【进阶篇 】

1.Django自带的分页

可以参考:Python之路【第十七篇】:Django【进阶篇 】

你数据量太多的时候页面一下子展示不了,这时就需要用到分页功能。

分批获取数据:

models.UserInfo.objects.all()[0:10]
models.UserInfo.objects.all()[10:20]

实际自带的可以这样

 在view.py中这样:

#主页
def index(request):
        #自动分页
        current_page = request.GET.get('page')
        from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage   #PageNotAnInteger页面不是整数时;EmptyPage页面是负数
        secfile_list = models.anfu.objects.all()   #获取全部数据
        paginator = Paginator(secfile_list,10)     #每10个一页  
        # per_page: 每页显示条目数量
        # count:    数据总个数
        # num_pages:总页数
        # page_range:总页数的索引范围,如: (1,10),(1,200)
        # page:     page对象
#增加异常,pagesh是非数字或者负数则跳到第一页
        try:
            posts = paginator.page(current_page)
except PageNotAnInteger as e: posts = paginator.page(1) #.page(n)是第n页 except EmptyPage as e: posts = paginator.page(1)
           # has_next              是否有下一页
           # next_page_number      下一页页码
           # has_previous          是否有上一页
           # previous_page_number  上一页页码
           # object_list           分页之后的数据列表
           # number                当前页
           # paginator             paginator对象
       return render(request, 'index.html', {'posts': posts})

对应到index.html这样:post.object_list

<body>
        <tbody>
            {% for row in posts.object_list %}
            <tr>
                <td>{{ row.id }}</td>
                <td>{{ row.CaseName }}</td>
  
            </tr>
            {% endfor %}
        </tbody>

    <div>
            {% if posts.has_previous %}  //显示是否有上一页
                <a href="/index?page={{ posts.previous_page_number }}">上一页</a>
            {% endif %}
      //显示页码范围
            {% for num in posts.paginator.page_range %}
                <a href="/index?page={{ num }}">{{ num }}</a>
            {% endfor %}
{% if posts.has_next %} //显示是否有下一页
<a href="/index?page={{ posts.next_page_number }}">下一页</a> {% endif %} </div>

 注:这个自带的分页只能在Django用,而且有一个弊端就是页码范围会全部显示在页面上,当数目太多就比较难看了。

 这时就需要自定义分页了,而且可以将其复用到其他程序~

2.自定义分页组件

 

def index(request):
        #分页之自定义分页
        #表示用户当前想要访问的页码
        current_page = request.GET.get('page')
        current_page = int(current_page)
        #每页显示数据个数
        per_page = 10
        start = (current_page-1) * per_page
        end = current_page * per_page
        secfile_list = models.anfu.objects.all()[start:end]

        return render(request, 'index.html', {'secfile_list': secfile_list})
初步分页展示

 但问题是代码有点多,页码多了就不好弄了。我们写个

#定义一个page类
class PageInfo(object):
    def __init__(self,current_page,per_page):
        #异常try,如果用户输入不是数字时,自动跳到page1
        try:
            self.current_page = int(current_page)
        except Exception as e:
            self.current_page = 1
        self.per_page = per_page #每页显示多少条
    def start(self):
        return (self.current_page-1) * self.per_page
    def end(self):
        return self.current_page * self.per_page

#主页
def index(request):
  #分页之自定义分页
  #表示用户当前想要访问的页码
  current_page = request.GET.get('page')
  page_info
= PageInfo(current_page,10)   secfile_list = models.anfu.objects.all()[page_info.start():page_info.end()]   return render(request, 'index.html', {'secfile_list': secfile_list})

类做好了,简化了代码,那下一步怎么显示页码呢?

>>> divmod(101,10)
(10, 1)
>>> divmod(100,10)
(10, 0)
#这可以看到,要想知道页数,需要知道总页数
------class里.......
a,b = divmod(all_count,per_page)
if b:
a = a +1
self.all_pager = a
return render(request, 'index.html', {'secfile_list': secfile_list,'page_info':page_info}
 在py中的定义,传个函数名它会自动执行;
{{ page_info.pager }}在index.html中实际也会返回,
但默认返回的是 <a href='/index/?page=1'>1</a> ;原因是为防止XSS攻击。

 解决方法就是:(就是标记一下这个东西是安全的额,就会显示出来)

{{ page_info.pager |safe }}
#定义一个page类
class PageInfo(object):
    def __init__(self,current_page,all_count,per_page):
        """

        :param current_page:
        :param all_count: 数据库总行数
        :param per_page: 每页显示的行数
        """
        #异常try,如果用户输入不是数字时
        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
    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='/index/?page=1'>1</a>"
        # return v
        page_list =[]
        for i in range(1,self.all_pager+1):
            if i == self.current_page:
                temp = "<a style='display:inline-block;padding:5px;margin:5px;background-color:red;' href='/index/?page=%s'>%s</a>" %(i,i)
            else:
                temp = "<a style='display:inline-block;padding:5px;margin:5px' href='/index/?page=%s'>%s</a>" % (i, i)
            page_list.append(temp)
        return ''.join(page_list)   #把列表中的每个元素都拼接起来


#主页
def index(request):
        #分页之自定义分页
        #表示用户当前想要访问的页码
  all_count = models.anfu.objects.all().count()  #总页数
  current_page = request.GET.get('page')
  page_info = PageInfo(current_page,all_count,5)
  secfile_list = models.anfu.objects.all()[page_info.start():page_info.end()]

  return render(request, 'index.html', {'secfile_list': secfile_list,'page_info':page_info})

----------html----------
{{ page_info.pager |safe }}
定义的类,可标记本页背景小展示

 

 但页面把所有的页面都展示出来了,太多了,我们只想一页展示11个页码:

#定义一个page类
class PageInfo(object):
    def __init__(self,current_page,all_count,per_page,base_url,show_page):
        """

        :param current_page:
        :param all_count: 数据库总行数
        :param per_page: 每页显示的行数
        """
        #异常try,如果用户输入不是数字时
        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='/index/?page=1'>1</a>"
        # return v
        page_list =[]
        half = int((self.show_page-1)/2)  #(11-1)/2=5
        #如果数据总页数< 11
        if self.all_pager < self.show_page:
            begin = 1
            stop = self.all_pager + 1
        #如果总页数 >11
        else:
            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

        # begin = self.current_page - half
        # stop = self.current_page + half +1  #最后一个取不到,再加一
        if self.current_page <= 1:
            prev = "<a style='display:inline-block;padding:5px;margin:5px' href='#'>上一页</a>"
        else:
            prev = "<a style='display:inline-block;padding:5px;margin:5px' href='%s?page=%s'>上一页</a>" %(self.base_url,self.current_page-1,)
        page_list.append(prev)
        for i in range(begin,stop):
            if i == self.current_page:
                temp = "<a style='display:inline-block;padding:5px;margin:5px;background-color:red;' href='%s?page=%s'>%s</a>" %(self.base_url,i,i)
            else:
                temp = "<a style='display:inline-block;padding:5px;margin:5px' href='/index/?page=%s'>%s</a>" % (i, i)
            page_list.append(temp)
        #下一页
        if self.current_page >= self.all_pager:
            nex = "<a style='display:inline-block;padding:5px;margin:5px' href='#'>下一页</a>"
        else:
            nex = "<a style='display:inline-block;padding:5px;margin:5px' href='%s?page=%s'>下一页</a>" %(self.base_url,self.current_page+1,)
        page_list.append(nex)
        return ''.join(page_list)   #把列表中的每个元素都拼接起来


#主页
def index(request):
    #去请求的cookie中找凭证;有明文的和带签名的两种方式
    #tk = request.COOKIES.get('ticket')
    tk = request.get_signed_cookie('ticket',default="0",salt='shannon')
    if  tk != "asasasasasaas":
        return redirect('/login/')

    else:
        #去数据库获取数据,(原始的)
        ##secfile_list = sqlheper.get_list("select id,CaseName,CaseType,Level,Cause,Result from anfu",[])
        #secfile_list = models.anfu.objects.all()
        #return render(request,'index.html',{'secfile_list':secfile_list})

        #分页之自定义分页
        #表示用户当前想要访问的页码
        all_count = models.anfu.objects.all().count()  #总页数
        current_page = request.GET.get('page')
        page_info = PageInfo(current_page,all_count,3,'/index',10)
        secfile_list = models.anfu.objects.all()[page_info.start():page_info.end()]

        return render(request, 'index.html', {'secfile_list': secfile_list,'page_info':page_info})
备注一下没加bootrap的原生态自定义分页

增添bootstrap;然后把类单独拿出来,下次用时再

from utils.pager import PageInfo

也就是说新建个utils文件夹并建个pager.py:(一生用起来~)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#定义一个page类
class PageInfo(object):
    def __init__(self,current_page,all_count,per_page,base_url,show_page):
        """

        :param current_page:
        :param all_count: 数据库总行数
        :param per_page: 每页显示的行数
        """
        #异常try,如果用户输入不是数字时
        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='/index/?page=1'>1</a>"
        # return v
        page_list =[]
        half = int((self.show_page-1)/2)  #(11-1)/2=5
        #如果数据总页数< 11
        if self.all_pager < self.show_page:
            begin = 1
            stop = self.all_pager + 1
        #如果总页数 >11
        else:
            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

        # begin = self.current_page - half
        # stop = self.current_page + half +1  #最后一个取不到,再加一
        if self.current_page <= 1:  #应用bootstrap: class='disabled'..
            prev = "<li class='disabled'><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:
                temp = "<li class='active'><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i)
            else:
                temp = "<li><a href='/index/?page=%s'>%s</a></li>" % (i, i)
            page_list.append(temp)
        #下一页
        if self.current_page >= self.all_pager:
            nex = "<li class='disabled'><a href='#'>下一页</a>"
        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)   #把列表中的每个元素都拼接起来

然后再对应的应用就引入views.py:

from utils.pager import PageInfo

#主页
def index(request):
    #去请求的cookie中找凭证;有明文的和带签名的两种方式
    #tk = request.COOKIES.get('ticket')
    tk = request.get_signed_cookie('ticket',default="0",salt='xxxnnon')
    if  tk != "asasasasasaas":
        return redirect('/login/')

    else:
        #去数据库获取数据,(原始的)
        ##secfile_list = sqlheper.get_list("select id,CaseName,CaseType,Level,Cause,Result from anfu",[])
        #secfile_list = models.anfu.objects.all()
        #return render(request,'index.html',{'secfile_list':secfile_list})

        #分页之自定义分页
        #表示用户当前想要访问的页码
        all_count = models.anfu.objects.all().count()  #总页数
        current_page = request.GET.get('page')
        page_info = PageInfo(current_page,all_count,6,'/index',10)
        secfile_list = models.anfu.objects.all()[page_info.start():page_info.end()]

        return render(request, 'index.html', {'secfile_list': secfile_list,'page_info':page_info})
直接import再传入传入参数就行

再传入html:

    <nav aria-label="Page navigation">
      <ul class="pagination pagination-sm">
              {{ page_info.pager |safe }}
      </ul>
    </nav>
字符串转换为函数

ethtool

猜你喜欢

转载自www.cnblogs.com/ethtool/p/12290376.html