• 01: 自定义分页


    目录:

    1.1 自定义分页     返回顶部

      1、创建步骤

          第一步:创建views.py视图函数

          第二步:user_list.html网页文件

          第三步:utils/pagination.py文件中写Page类处理分页插件

      2、定义插件说明

          注:utils文件夹需要自己在Django项目下创建
          1、 为了防止xss攻击,网站前台收到数据默认都是字符串
          2、 可以使用mark_safe模块在前台html文件中或在后台python文件中指定将这些字符串解释成html语言

          3、 在html文件中指定后台传递的字符串是安全的:
              {{ page_str|safe }}

          4、 也可以在python后台传递前转换成安全数据
              page_str = mark_safe(page_list)

    from django.shortcuts import render
    
    from utils import pagination
    #1 使用for循环模拟从数据库取出999条数据
    LIST = []
    for i in range(999):
        LIST.append(i)
    
    def user_list(request):
        #2 GET可以获取url中传入的参数,用p来接收,如果并设置默认值为: 1
        current_page = request.GET.get('p',1)
        current_page = int(current_page)
    
        #3 实例化处理分页的Page类,并传入参数:当前页面,和共有多少条数据
        page_obj = pagination.Page(current_page,len(LIST),)
    
        #4 调用类方法计算,每页显示的数据,第一条数据索引和最后一条数据索引
        data = LIST[page_obj.start:page_obj.end]
    
        #5 在调用Page类的page_str方法时传入url路径,以便适应更多场景
        page_str = page_obj.page_str('/user_list/')
        
        return  render(request,'user_list.html',{'li':data,'page_str':page_str})
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            {#1  页面下面跳转索引样式  #}
            .pagination .page{
                display: inline-block;
                padding: 5px;
                background-color: #eeeeee;
                margin: 5px;}
            {#2  页面下面跳转索中当前页面a标签添加颜色  #}
            .pagination .page.active{
                background-color: brown;
                color: white;}
        </style>
    </head>
    <body>
        {#1 页面内容 #}
        <ul>
            {% for item in li %}
                <li>{{ item }}</li>
            {% endfor %}
        </ul>
    
        {#2  页面下面跳转的索引  #}
        <div class="pagination">
            {{ page_str }}
        </div>
    </body>
    </html>
    user_list.html
    from django.utils.safestring import mark_safe
    class Page:
        """
            current_page: 目前显示第几页内容
            data_count: 获取的数据总共有多少条
            per_page_count:每页放多少条数据
            pager_num:每个页面下面显示索引的个数
        """
        def __init__(self, current_page, data_count, per_page_count=10, pager_num=7):
            self.current_page = current_page
            self.data_count = data_count
            self.per_page_count = per_page_count
            self.pager_num = pager_num
            print(self.current_page)
            print(self.data_count)
    
        @property
        def start(self):
            #每页显示的数据,第一条数据索引
            return (self.current_page - 1) * self.per_page_count
    
        @property
        def end(self):
            #每页显示的数据,条目的最后一条索引
            return self.current_page * self.per_page_count
    
        @property
        def total_count(self):
            #v是商,y是余数,这里v正好就是计算可分的页数
            v, y = divmod(self.data_count, self.per_page_count)
            if y:        #相除的余数大于0加1
                v += 1
            return v
    
    
        def page_str(self, base_url):
            page_list = []
            if self.total_count < self.pager_num:    #数据可总页数小于一页可显示的条数(total_count是类中的函数)
                start_index = 1
                end_index = self.total_count + 1     #end_index是数据总共可以分成的页数
            else:                                    #显示前面几页时增加页面,下面的页面索引不滚动增加
                if self.current_page <= (self.pager_num + 1) / 2:
                    start_index = 1
                    end_index = self.pager_num + 1
                else:
                    start_index = self.current_page - (self.pager_num - 1) / 2
                    end_index = self.current_page + (self.pager_num + 1) / 2
                    #防止页面跳转后索引大于总页面个数
                    if (self.current_page + (self.pager_num - 1) / 2) > self.total_count:
                        end_index = self.total_count + 1
                        start_index = self.total_count - self.pager_num + 1
    
            if self.current_page == 1:
                prev = '<a class="page" href="javascript:void(0);">上一页</a>'
            else:
                prev = '<a class="page" href="%s?p=%s">上一页</a>' % (base_url, self.current_page - 1,)
            page_list.append(prev)
            for i in range(int(start_index), int(end_index)):
                if i == self.current_page:                                        # 将当前页面的a标签变色
                    temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url, i, i)
                else:
                    temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url, i, i)
                page_list.append(temp)
            if self.current_page == self.total_count:
                nex = '<a class="page" href="javascript:void(0);">下一页</a>'
            else:
                nex = '<a class="page" href="%s?p=%s">下一页</a>' % (base_url, self.current_page + 1,)
            page_list.append(nex)
            #在input中输入页码,点击GO就会跳转
            jump = """
            <input type='text'  /><a onclick ='jumpTo(this, "%s?p=");'>GO</a>
            <script>
                function jumpTo(ths,base){
                    var val = ths.previousSibling.value;
                    location.href = base + val;
                }
            </script>
            """ % (base_url,)
            page_list.append(jump)
            page_str = mark_safe("".join(page_list))
            return page_str
    utils/pagination.py

       3、效果图

               

    1.2 Django自带分页     返回顶部

      1、Django自带分页基本使用

    >>> from django.core.paginator import Paginator
    >>> objects = ['john', 'paul', 'george', 'ringo']
    
    >>> p = Paginator(objects, 2)                #实例化分页实例,每页显示两条数据
    >>> p.count                            #共有数据有多少条
    4
    >>> p.num_pages                        #总共可以分多少页
    2
    
    >>> p.page_range                        #获取分页从第几页到第几页
    range(1, 3)
    >>> page1 = p.page(1)                    #获取第一页
    >>> page1
    <Page 1 of 2>
    >>> page1.object_list                    #显示第一页具体内容
    ['john', 'paul']
    >>> page2 = p.page(2)
    >>> page2.object_list
    ['george', 'ringo']
    
    >>> page2.has_next()                    #判断是否有下一页
    False
    >>> page2.has_previous()                #判断是否有上一页
    True
    >>> page2.has_other_pages()            #判断是否有其他页
    True
    
    >>> page2.next_page_number()            #获取第二页的下一页页码
    Traceback (most recent call last):
    ...
    EmptyPage: That page contains no results
    >>> page2.previous_page_number()        #获取第二页的上一页页码
    1
    >>> page2.start_index()                 # 获取第2页的第一条数据在所有数据中的索引
    3
    >>> page2.end_index()                     #获取第2页的最后一条数据在所有数据中的索引
    4
    Django自带分页:命令行测试功能

      2、Django自带分页实现数据分页展示 

    from django.shortcuts import render
    
    data = []
    for i in range(200):
       data.append(i)
    
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    from django.shortcuts import render
    
    def user_list(request):
        contact_list = data
        paginator = Paginator(contact_list, 10) # Show 25 contacts per page
    
        page = request.GET.get('page')
        try:
            contacts = paginator.page(page)
        except PageNotAnInteger:        #页数为负数(或不是整数)返回第一页
            contacts = paginator.page(1)
        except EmptyPage:
            contacts = paginator.page(paginator.num_pages)    #页数超出范围返回最后一页
        return render(request, 'user_list.html', {'contacts': contacts})
    views.py
    {% load tags %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <style>
            ul li{
                list-style: none;
            }
            .pagination li{
                float: left;
                margin: 5px;
            }
            .active{
                background-color: brown;
            }
        </style>
    </head>
    <body>
    {% for contact in contacts %}
        <p>{{ contact }}</p>
    {% endfor %}
    
    <div class="pagination">
        <nav aria-label="Page navigation">
          <ul class="pagination">
            {% if contacts.has_previous %}
                <li><a href="?page={{ contacts.previous_page_number }}">上一页</a></li>
            {% endif %}
    
            {% for loop_counter in contacts.paginator.page_range %}
                {% render_page_ele loop_counter contacts %}
            {% endfor %}
    
            {% if contacts.has_next %}
                <li><a href="?page={{ contacts.next_page_number }}">下一页</a></li>
            {% endif %}
          </ul>
        </nav>
    </div>
    </body>
    </html>
    user_list.html
    from django import template
    from django.utils.safestring import mark_safe
    
    register = template.Library()     #对象名register不可变
    #分页
    @register.simple_tag
    def render_page_ele(loop_counter,query_sets):
       #query_sets.number 获取当前页
       #loop_counter循环到第几页
       if abs(query_sets.number -loop_counter) <= 3:
          ele_class = ""
          if query_sets.number == loop_counter:
             ele_class = 'active'
          ele = '''<li class="%s"><a href="?page=%s">%s</a></li>'''%(ele_class,loop_counter,loop_counter)
          return mark_safe(ele)
       return ''
    app01/templatetags/tags.py

      3、效果图

                 

  • 相关阅读:
    题解 [CF891C] Envy
    题解 [BZOJ4710] 分特产
    题解 [BZOJ2159] Crash的文明世界
    题解 [BZOJ4144] Petrol
    #leetcode刷题之路1-两数之和
    week 7 文件操作与模板
    coursera 北京大学 程序设计与算法 专项课程 STL week8 list
    coursera 北京大学 程序设计与算法 专项课程 完美覆盖
    JSTL标签库不起作用的解决方案 .(转)
    javax.servlet.jsp.PageContext.getELContext()Ljavax/el/ELContext解决办法(转)
  • 原文地址:https://www.cnblogs.com/xiaonq/p/8016607.html
Copyright © 2020-2023  润新知