zoukankan      html  css  js  c++  java
  • django -- 分页

    前戏

    分页是我们经常遇到的,只要有表单,数据量大的时候,都要用到分页,所以说分页是web开发里必不可少的知识点。

    分页第一版

    使用列表生成式来制造一些数据

    user_data = [{'name':'zouzou{}'.format(i),'pwd':'abc{}'.format(i)} for i in range(1,303)]

    在写个视图函数,把数据传给html文件进行渲染

    def user_list(request):
        
    
        return render(request, 'user_list.html', {'data': user_data})

    写一个HTML文件用于展示数据

    {% extends 'layout.html' %}
    
    {% block content %}
        <table class="table table-bordered">
            <thead>
                <th>序号</th>
                <th>账号</th>
                <th>密码</th>
            </thead>
            <tbody>
            {% for user in data %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ user.name }}</td>
                    <td>{{ user.pwd }}</td>
                </tr>
            {% endfor %}
    
            </tbody>
        </table>
    
    
    
    {% endblock content %}
    user_list.html
    {% extends 'layout.html' %}是继承母版,下面写的自己的内容。这样的效果是所有的数据都显示在了一页,肯定不是我们想要的结果。在来改写一下视图函数
    def user_list(request):
        try:
            current_page = int(request.GET.get('page',1))  # 获取表单里提交的页码,默认为1
            if current_page <= 0:
                current_page = 1
        except Exception as e:
            current_page = 1
    
        par_num = 10  # 每页显示的数量
        all_count = len(user_data)  # 总数据量
        total_num, more=divmod(all_count,par_num)  # 页码数和余数
        if more:  # 有余数,页码加1
            total_num += 1
    
        start = (current_page-1) * par_num  # 每页的开始值
        end = current_page * par_num  # 每页的结束值
    
        return render(request, 'user_list.html', {'data': user_data[start:end],
                                                  "total_num":range(1, total_num+1)})
    "total_num":range(1, total_num+1)} 给HTMl文件,方便渲染

    修改对应的html文件
    {% extends 'layout.html' %}
    
    {% block content %}
        <table class="table table-bordered">
            <thead>
                <th>序号</th>
                <th>账号</th>
                <th>密码</th>
            </thead>
            <tbody>
            {% for user in data %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ user.name }}</td>
                    <td>{{ user.pwd }}</td>
                </tr>
            {% endfor %}
    
            </tbody>
        </table>
    
          <nav sria-label="Page navigation">
                <ul class="pagination">
                    {% for num in total_num %}
                        <li><a href="/user_list/?page={{ num }}">{{ num }}</a></li>
                    {% endfor %}
    
    
                </ul>
    
            </nav>
    
    {% endblock content %}

    刷新页面查看效果

    分页第二版(指定页码个数)

    只需要更改视图函数就可以了

    # 分页
    def user_list(request):
        try:
            current_page = int(request.GET.get('page',1))  # 获取表单里提交的页码,默认为1
            if current_page <= 0:
                current_page = 1
        except Exception as e:
            current_page = 1
    
        max_show = 11  # 最多显示的页码数
        half_show = max_show // 2  # 左右显示的个数
    
        page_start = current_page - half_show  # 开始的页码为当前页码减掉一半
        page_end = current_page + half_show  # 结束页码
    
        par_num = 10  # 每页显示的数量
        all_count = len(user_data)  # 总数据量
        total_num, more=divmod(all_count,par_num)  # 页码数和余数
        if more:  # 有余数,页码加1
            total_num += 1
    
        '''
        做判断,要不然点第一页,显示了负数,点最后一页,还往上加
        '''
        # 总页码数小于最大显示数,显示总页码数
        if total_num <= max_show:
            page_start = 1
            page_end = max_show
        else:
            # 总页码数大于最大显示数,最多显示11个
            if current_page <= half_show:
                page_start = 1
                page_end = max_show
            elif current_page+half_show >= total_num:
                page_start = total_num-max_show+1
                page_end = total_num
            else:
                page_start = current_page - half_show
                page_end = current_page + half_show
    
        start = (current_page-1) * par_num  # 每页的开始值
        end = current_page * par_num  # 每页的结束值
    
        return render(request, 'user_list.html', {'data': user_data[start:end],
                                                  "total_num":range(page_start, page_end+1)})

    分页第三版(增加下一页,上一页,首页,尾页)

    把html里循环展示页码的代码在服务端实现

    def user_list(request):
        try:
            current_page = int(request.GET.get('page',1))  # 获取表单里提交的页码,默认为1
            if current_page <= 0:
                current_page = 1
        except Exception as e:
            current_page = 1
    
        max_show = 11  # 最多显示的页码数
        half_show = max_show // 2  # 左右显示的个数
    
        page_start = current_page - half_show  # 开始的页码为当前页码减掉一半
        page_end = current_page + half_show  # 结束页码
    
        par_num = 10  # 每页显示的数量
        all_count = len(user_data)  # 总数据量
        total_num, more=divmod(all_count,par_num)  # 页码数和余数
        if more:  # 有余数,页码加1
            total_num += 1
    
        '''
        做判断,要不然点第一页,显示了负数,点最后一页,还往上加
        '''
        # 总页码数小于最大显示数,显示总页码数
        if total_num <= max_show:
            page_start = 1
            page_end = max_show
        else:
            # 总页码数大于最大显示数,最多显示11个
            if current_page <= half_show:
                page_start = 1
                page_end = max_show
            elif current_page+half_show >= total_num:
                page_start = total_num-max_show+1
                page_end = total_num
            else:
                page_start = current_page - half_show
                page_end = current_page + half_show
        # 存放li标签的列表
        html_list = []
    
        first_li = '<li><a href="/user_list/?page=1">首页</a></li>'
        html_list.append(first_li)
    
        if current_page == 1:
            prev_li = '<li class="disabled"><a><<</a></li>'
        else:
            prev_li = '<li><a href="/user_list/?page={0}"><<</a></li>'.format(current_page - 1)
        html_list.append(prev_li)
    
        for num in range(page_start, page_end + 1):
            if current_page == num:
                li_html = '<li class="active"><a href="/user_list/?page={0}">{0}</a></li>'.format(num)
            else:
                li_html = '<li><a href="/user_list/?page={0}">{0}</a></li>'.format(num)
            html_list.append(li_html)
    
        if current_page == total_num:
            next_li = '<li class="disabled"><a>>></a></li>'
        else:
            next_li = '<li><a href="/user_list/?page={0}">>></a></li>'.format(current_page + 1)
    
        html_list.append(next_li)
    
        last_li = '<li><a href="/user_list/?page={}">尾页</a></li>'.format(total_num)
        html_list.append(last_li)
    
        html_str = mark_safe(''.join(html_list))
        start = (current_page-1) * par_num  # 每页的开始值
        end = current_page * par_num  # 每页的结束值
    
        return render(request, 'user_list.html', {'data': user_data[start:end],
                                                  "total_num":range(page_start, page_end+1),
                                                  'html_str': html_str})

    最后一版

     前面写的三版,分页的代码都在一个视图函数里面,如果别的页面页要用到的话,我们还要复制一遍,这样代码显的很low,我们可以在我们项目下面新建一个文件夹utils,在新建一个py文件,把我们分页的代码写到里面

    """
    分页器
    """
    
    from django.utils.safestring import mark_safe
    
    
    class Pagination:
        
        def __init__(self, request, all_count, per_num=10, max_show=11):
            # 基本的URL
            self.base_url = request.path_info
            # 当前页码
            try:
                self.current_page = int(request.GET.get('page', 1))
                if self.current_page <= 0:
                    self.current_page = 1
            except Exception as e:
                self.current_page = 1
            # 最多显示的页码数
            self.max_show = max_show
            half_show = max_show // 2
            
            # 每页显示的数据条数
            self.per_num = per_num
            # 总数据量
            self.all_count = all_count
            
            # 总页码数
            self.total_num, more = divmod(all_count, per_num)
            if more:
                self.total_num += 1
            
            # 总页码数小于最大显示数:显示总页码数
            if self.total_num <= max_show:
                self.page_start = 1
                self.page_end = self.total_num
            else:
                # 总页码数大于最大显示数:最多显示11个
                if self.current_page <= half_show:
                    self.page_start = 1
                    self.page_end = max_show
                elif self.current_page + half_show >= self.total_num:
                    self.page_end = self.total_num
                    self.page_start = self.total_num - max_show + 1
                else:
                    self.page_start = self.current_page - half_show
                    self.page_end = self.current_page + half_show
        
        @property
        def start(self):
            return (self.current_page - 1) * self.per_num
        
        @property
        def end(self):
            return self.current_page * self.per_num
        
        @property
        def show_li(self):
            # 存放li标签的列表
            html_list = []
            
            first_li = '<li><a href="{}?page=1">首页</a></li>'.format(self.base_url)
            html_list.append(first_li)
            
            if self.current_page == 1:
                prev_li = '<li class="disabled"><a><<</a></li>'
            else:
                prev_li = '<li><a href="{1}?page={0}"><<</a></li>'.format(self.current_page - 1, self.base_url)
            html_list.append(prev_li)
            
            for num in range(self.page_start, self.page_end + 1):
                if self.current_page == num:
                    li_html = '<li class="active"><a href="{1}?page={0}">{0}</a></li>'.format(num, self.base_url)
                else:
                    li_html = '<li><a href="{1}?page={0}">{0}</a></li>'.format(num, self.base_url)
                html_list.append(li_html)
            
            if self.current_page == self.total_num:
                next_li = '<li class="disabled"><a>>></a></li>'
            else:
                next_li = '<li><a href="{1}?page={0}">>></a></li>'.format(self.current_page + 1, self.base_url)
            
            html_list.append(next_li)
            
            last_li = '<li><a href="{1}?page={0}">尾页</a></li>'.format(self.total_num, self.base_url)
            html_list.append(last_li)
            
            return mark_safe(''.join(html_list))

    在视图函数里面调用

    def user_list(request):
        page = Pagination(request, len(users))
    
        return render(request, 'user_list.html',
                      {
                          "data": users[page.start:page.end],
                          # 'total_num': range(page_start, page_end + 1)
                          'html_str': page.show_li
                      })
    # 展示客户列表
    def customer_list(request):
        all_customer = models.Customer.objects.all()
        page = Pagination(request, all_customer.count())
    
        return render(request, 'crm/customer_list.html',
                      {"all_customer": all_customer[page.start:page.end], 'pagination': page.show_li})
  • 相关阅读:
    在GridView1的RowEditing获取GridView1里面绑定的某一字段
    仿淘宝网站的导航标签效果!
    ASP.NET Cookies简单应用 [ASP.NET | Cookies]
    UpdatePanel使用时注意说明
    Asp.net(C#)显示所有缓存 清除所有缓存
    计算字符在字符串是出现的次数
    新接触了ActionScript3.0 拿出来晒晒~
    转载Windows XP_32bit、Windows 7_32bit、Windows 7_64bit乱序任意安装方法
    新博客庆祝
    Android 电视关闭的动画效果
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/11343088.html
Copyright © 2011-2022 走看看