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 %}
相关推荐
忧郁的Mr.Li31 分钟前
SpringBoot中实现多数据源配置
java·spring boot·后端
玄同76536 分钟前
从 0 到 1:用 Python 开发 MCP 工具,让 AI 智能体拥有 “超能力”
开发语言·人工智能·python·agent·ai编程·mcp·trae
小瑞瑞acd1 小时前
【小瑞瑞精讲】卷积神经网络(CNN):从入门到精通,计算机如何“看”懂世界?
人工智能·python·深度学习·神经网络·机器学习
火车叼位1 小时前
也许你不需要创建.venv, 此规范使python脚本自备依赖
python
暮色妖娆丶1 小时前
SpringBoot 启动流程源码分析 ~ 它其实不复杂
spring boot·后端·spring
火车叼位1 小时前
脚本伪装:让 Python 与 Node.js 像原生 Shell 命令一样运行
运维·javascript·python
Coder_Boy_1 小时前
Deeplearning4j+ Spring Boot 电商用户复购预测案例中相关概念
java·人工智能·spring boot·后端·spring
孤狼warrior1 小时前
YOLO目标检测 一千字解析yolo最初的摸样 模型下载,数据集构建及模型训练代码
人工智能·python·深度学习·算法·yolo·目标检测·目标跟踪
Java后端的Ai之路2 小时前
【Spring全家桶】-一文弄懂Spring Cloud Gateway
java·后端·spring cloud·gateway
Katecat996632 小时前
YOLO11分割算法实现甲状腺超声病灶自动检测与定位_DWR方法应用
python