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 %}
相关推荐
Data_Journal3 小时前
用于网页抓取的 Node-unblocker
大数据·开发语言·数据库·python·scrapy
豆角焖肉4 小时前
SSM 聚合项目搭建:多 Maven 模块项目
开发语言·python·pycharm
青 春 记 忆4 小时前
零基础入门python20:Flask配置、扩展和蓝图拆分
python·flask·后端开发
m0_380743875 小时前
为 OpenAI 兼容接口配置教程
开发语言·python·node.js
凤山老林5 小时前
Spring Boot 3.x AOT 编译实战:从原理、踩坑到生产落地
java·spring boot·后端
博傅5 小时前
Spring 核心原理
java·后端·spring
用户938515635076 小时前
掘金风格后端数据库设计实战:从用户表到分布式架构,一文搞定
后端·sql
拾光师6 小时前
Hadoop 三种运行模式:从单机调试到生产集群,一路搭过来
后端
leisoo80977 小时前
ig50数据落盘ClickHousevsTimescaleDBvsDuckDB实测对比 IG50免费开源股票数据API接口
开发语言·jvm·数据库·python·json
进阶的小名7 小时前
Spring AI 2.0 探索:多 OpenAI-Compatible 模型接入,以及下一代 Session 记忆管理
java·人工智能·后端·gpt·spring·ai·chatgpt