django处理分页

当数据库量比较大的时候一定要分页查询的

在django中操作数据库进行分页

python 复制代码
queryset = models.PrettyNum.objects.all()   #查询所有
queryset = models.PrettyNum.objects.all()[0:10]    #查询出1-10列
queryset = models.PrettyNum.objects.filter(mobile__contains='136')[0:10]  #查询出符合条件的前10列

queryset = models.PrettyNum.objects.all().count()   #查询有多少条数据,返回的是一个数字

#第一页
queryset = models.PrettyNum.objects.all()[0:10]

#第二页
queryset = models.PrettyNum.objects.all()[10:20]

#第三页
queryset = models.PrettyNum.objects.all()[20:30]

1、封装分页的插件类

这个分页插件要实现的是如下效果,当前页和前5页,后5页,上一页和下一页,还有首页和尾页

在app01下创建一个分页的的工具类,pagination.py

pagination.py的内容:

在初始化函数中,需要的参数有

request:请求的对象,通过对象获取url传的参数

queryset:符合条件的数据(根据这个数据库给他镜像分页处理)

page_size: 每页显示多少条数据, 不传默认显示10条数据库

page_param:在URL中传递的获取分页的参数,例如 /pretty/list/?page=12, 默认是page

plus: 显示当前页的前或后几页(页码),默认是5

在初始化函数中计算出总页数

在函数html就是生成html页面,最后返回这个页码html页面的字符串

python 复制代码
from django.utils.safestring import mark_safe
class Pagination():
    def __init__(self,request,queryset,page_size=10,page_param="page",plus=5):
        """
        :param request: 请求的对象
        :param queryset: 符合条件的数据(根据这个数据库给他镜像分页处理)
        :param page_size: 每页显示多少条数据
        :param page_param: 在URL中传递的获取分页的参数,例如 /pretty/list/?page=12
        :param plus: 显示当前页的前或后几页(页码)
        """
        page = request.GET.get(page_param,"1")
        if page.isdecimal():
            page = int(page)
        else:
            page = 1

        self.page = page
        self.page_size = page_size
        self.start = (page-1)* page_size
        self.end = page * page_size

        self.page_queryset = queryset[self.start:self.end]
        total_count = queryset.count()
        total_page_count,div = divmod(total_count,page_size)
        if div:
            total_page_count += 1
        self.total_page_count = total_page_count
        self.plus = plus

    def html(self):
        #计算出,显示当前页的前5页,后5页
        if self.total_page_count <= 2 * self.plus + 1:
            #数据库中的数据比较少,没有11页
            start_page = 1
            end_page = self.total_page_count
        else:
            # 数据库中的数据比较多,大于11页
            # 当前页<5时,(小级值)
            if self.page <= self.plus:
                start_page = 1
                end_page = 2 * self.plus + 1
            else:
                # 当前页大于5
                #当前页 + 5 > 总页面
                if (self.page + self.plus) > self.total_page_count:
                    start_page = self.total_page_count - 2*self.plus
                    end_page = self.total_page_count
                else:
                    start_page = self.page - self.plus
                    end_page = self.page + self.plus
        # 页码
        page_str_list = []
        page_str_list.append('<li><a href="?page={}">首页</a></li>'.format(1))

        # 上一页
        if self.page > 1:
            prev = '<li><a href="?page={}">上一页</a></li>'.format(self.page -1)
        else:
            prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
        page_str_list.append(prev)

        #页面
        for i in range(start_page,end_page + 1):
            if i == self.page:
                ele = '<li class="active"><a href="?page={}">{}</a></li>'.format(i,i)
            else:
                ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
            page_str_list.append(ele)
        # 下一页
        if self.page < self.total_page_count:
            prev = '<li><a href="?page={}">下一页</a></li>'.format(self.page + 1)
        else:
            prev = '<li><a href="?page={}">下一页</a></li>'.format(self.total_page_count)
        page_str_list.append(prev)

        # 尾页
        page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(self.total_page_count))

        search_string = """
          <li>
          <form style="float:left; margin-left: -1px" method="get">
              <input name="page" style="position: relative;float: left;display: inline-block;width: 80px;border-radius: 0" type="text" class="form-control" placeholder="页码">
              <button style="border-radius: 0" class="btn btn-default" type="submit">跳转</button>
          </form>
    </li>
        
        """
        page_str_list.append(search_string)
        page_string = mark_safe("".join(page_str_list))
        return page_string

2、在视图函数中使用页码类

在views.py 中导入类,实例化类,通过context 把内容传给页面

python 复制代码
from django.shortcuts import render,redirect,HttpResponse
from django import forms
from app01 import models
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from app01.utils.pagination import Pagination


def pretty_list(request):
    """靓号列表"""

    data_dict = {}
    search_data = request.GET.get('q',"")
    if search_data:
        data_dict['mobile__contains'] = search_data
    #从数据库查询到数据,排序,使用order_by ,-level表示降序,level升序
    queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")
    page_obj = Pagination(request,queryset)
    context={
          "search_data": search_data,
        "queryset": page_obj.page_queryset,  #分页的数据
        "page_string":page_obj.html()    #页码
    }
    return render(request,'pretty_list.html',context)

3、在html中展示页码

在pretty_list.html的底部加上显示页面的

不管在哪个页面需要使用页码,只需要在要展示的地方加上下面的页码展示的就可以了,具体有多少页,根据数据条数,自动生成在page_string 变量中

html 复制代码
  <nav aria-label="Page navigation">
            <ul class="pagination">
                     {{ page_string }}
            </ul>
 </nav>

pretty_list.html的整体代码如下:

html 复制代码
{% extends 'layout.html' %}

{% block content %}
    <div class="container">
        <div style="margin-bottom: 10px">
            <a class="btn btn-success" href="/pretty/add/">新建靓号</a>
            <div style="float: right; width: 300px">
                <form method="get">
                    <div class="input-group">

                        <input type="text" name="q" class="form-control" placeholder="手机号搜索" value="{{ search_data }}">
                        <span class="input-group-btn">
                                <button class="btn btn-default" type="submit">
                                    <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
                                </button>
                          </span>

                    </div>
                </form>
            </div>
        </div>
        <div class="panel panel-default">
            <div class="panel-heading"><span class="glyphicon glyphicon-list" aria-hidden="true"></span> 靓号列表</div>
            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>号码</th>
                    <th>价格</th>
                    <th>级别</th>
                    <th>状态</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                {% for obj in queryset %}
                    <tr>
                        <td>{{ obj.id }}</td>
                        <td>{{ obj.mobile }}</td>
                        <td>{{ obj.price }}</td>
                        <td>{{ obj.get_level_display }}</td>
                        <td>{{ obj.get_status_display }}</td>
                        <td>
                            <a class="btn btn-primary btn-xs" href="/pretty/{{ obj.id }}/edit/">编辑</a>
                            <a class="btn btn-danger btn-xs" href="/pretty/{{ obj.id }}/delete/">删除</a>
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>

        <nav aria-label="Page navigation">
            <ul class="pagination">
                     {{ page_string }}
            </ul>
        </nav>
    </div>

{% endblock %}
相关推荐
D11_26 分钟前
Pandas缺失值处理
python·机器学习·数据分析·numpy·pandas
花生了什么树~.1 小时前
python基础知识(四)--if语句,for\while循环
python
IT毕设梦工厂2 小时前
计算机毕业设计选题推荐-在线拍卖系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计
luthane2 小时前
python 实现average mean平均数算法
开发语言·python·算法
码农研究僧2 小时前
Flask 实现用户登录功能的完整示例:前端与后端整合(附Demo)
python·flask·用户登录
Ylucius3 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
凡人的AI工具箱3 小时前
AI教你学Python 第11天 : 局部变量与全局变量
开发语言·人工智能·后端·python
sleP4o3 小时前
Python操作MySQL
开发语言·python·mysql
是店小二呀3 小时前
【C++】C++ STL探索:Priority Queue与仿函数的深入解析
开发语言·c++·后端
canonical_entropy3 小时前
金蝶云苍穹的Extension与Nop平台的Delta的区别
后端·低代码·架构