◢Django 分页+搜索

news2024/11/16 3:41:01

1、搜索数据

从数据库中获取数据,并进行筛选,xx__contains = q作为条件,查找的是xx列中有q的所有数据条

当有多个筛选条件时,将条件变成一个字典,传入 **字典 ,ORM会自行翻译并查找。

筛选电话号码这一列,若数据量过少,使用random库多次生成

<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="{% static '/js/jquery-3.6.0.min.js' %}"></script>
    <style>
        @import "{% static 'css/tab.css' %}";
    </style>
</head>
<body>
<form method="get">
<input type="text" name="search"><button type="submit">搜索</button>
</form>
<hr>
<table>
    <tr>
        <td>ID</td>
        <td>号码</td>
        <td>价格</td>
        <td>等级</td>
        <td>状态</td>
    </tr>
    {% for i in data %}
        <tr>
            <td>{{ i.id }}</td>
            <td>{{ i.phone }}</td>
            <td>{{ i.price }}</td>
            <td>{{ i.level }}</td>
            <td>{{ i.get_status_display }}</td>
        </tr>
    {% endfor %}
</table>
</body>
</html>
def in4(request):
    if request.method == 'GET':
        data_dict = {}
        search = request.GET.get('search')
        print(search)
        if search:
            data_dict['phone__contains'] = search
        # 获取数据库的数据
        querset = models.User.objects.filter(**data_dict).order_by('level')
        return render(request,'in4.html',{"data":querset})

输入筛选条件, 点击搜索,会自动更新页面并清除输入框中的内容

return 加入search,在input框中加入显示搜索的数据

placeholder="{{ search }}"

 2、加入分页

按照上节直接加上,会导致搜索与分页不能同时存在,要对page与search进行url拼接【字典.urlencode()】

request请求传递过来的参数,不允许对其进行更改,先对其进行深拷贝,在拷贝出的数据上进行page与search两个参数的修改。

import copy
req = copy.deepcopy(request.GET)#深拷贝get请求
req._mutable = True

req.setlist(key,iter)#iter必须是可迭代对象

req.urlencode()

设置一页显示的最大数据条数,获取page参数 ,对筛选后的数据进行分页截取,设置起始页与结束页至当前页的最大距离,循环设置分页的页码

import copy
req = copy.deepcopy(request.GET)#深拷贝get请求
req._mutable = True

page_size = 10
if request.GET.get('page'):
    current_page = int(request.GET.get('page'))
else:
    current_page = 1
page_count, count = divmod(data_count, page_size)  # 共有多少页
if count:
    page_count += 1
# 获取数据的起始位置与结束位置
start = int(current_page - 1) * page_size
if current_page == page_count:  # 当前页是最后一页时,数据并不是page_size条数据
    end = data_count
else:
    end = int(current_page) * page_size
print(start, end)
data = querset[start:end]#从筛选后的数据中进行的分页数据

#设置分页最大显示
plus = 3
if current_page <= plus + 1:
    start_page = 1
else:
    start_page = current_page - plus
# 当前页大于等于最终点页 结束页始终为终点页 ;当前页小于终点页减plus 结束页为当前页+plus
if current_page >= page_count - plus:
    end_page = page_count
else:
    end_page = current_page + plus
#在筛选好的数据基础上,点击2页时不会使得search条件失去效果
page_string = ''
for i in range(start_page, end_page+1):
    req.setlist('page',[i])
    if i == current_page:#为活动页增加样式,突出显示当前页
        page_string += f"<span style='background-color:#fff;'><a style='color:#000' href=?{req.urlencode()}>{i}</a></span>"
    else:
        page_string += f"<span><a href=?{req.urlencode()}>{i}</a></span>"
    page_string = mark_safe("".join(page_string))
return render(request,'in4.html',{"data":data,"page_string":page_string})

 3、上一页与下一页

在点击页码的情况下增加上一页下一页的按钮,当前看到的最后页码变为第一个页码。

看见第一页不显示上一页按钮,同样最后一页也不带按钮。

处于看不见首页,但又不超过加减页时,点击上一页会跳出合适的页码,应当设置page=1,拉回跳转位置,放置page变为负数,尾页也一样。

页码满足加减页时,实行最后一个页码变第一个页码,在当前页的页码基础上 加上 或 减去 plus的2倍

def  in4(request):
       ...
       if current_page <= plus + 1:
            pre = ''
        else:
            if current_page <= plus * 2:  # 当前页处于大于1个plus,小于2个plus页时,点击上一页,跳转到第1页
                req.setlist('page',[1])
                pre = f'<span class="updown"><a href=?{req.urlencode()}>首页</a></span>'
            else:
                req.setlist('page', [current_page - plus * 2])
                pre = f'<span class="updown"><a href=?{req.urlencode()}>上一页</a></span>'
        # 下一页同上一页一致
        if current_page >= page_count - plus:
            next = ''
        else:
            if current_page >= page_count - plus * 2:
                req.setlist('page',[page_count])
                next = f'<span class="updown"><a href=?{page_count}>尾页</a></span>'
            else:
                req.setlist('page',[current_page + plus * 2])
                next = f'<span class="updown"><a href=?{req.urlencode()}>下一页</a></span>'

4、封装

建立软件包,命名为utils

 在utils中建立SplitPage.py,整合前面程序,该封装的封装,该方法体的方法体,page_size与plus进行内定义

from django.utils.safestring import mark_safe
import copy
class Splitpagenumber:
    def __init__(self,request,queryset,page_size=10,plus=3):
        #确实获取到page,若没有则默认为首页
        if request.GET.get('page'):
            self.current_page = int(request.GET.get('page'))
        else:
            self.current_page = 1

        #拷贝get,为后续使用做准备
        req = copy.deepcopy(request.GET)
        req._mutable = True
        self.req = req

        #计算页码总数
        self.page_count,count = divmod(queryset.count(),page_size)
        if count:
            self.page_count += 1

        #为筛选好的数据进行分页
        start = int(self.current_page - 1) * page_size
        if self.current_page == self.page_count:
            end = queryset.count()
        else:
            end = int(self.current_page) * page_size
        self.page_data = queryset[start:end]  # 从筛选后的数据中进行的分页数据

        #
        self.plus=plus

    def html(self):
        if self.current_page <= self.plus + 1:
            start_page = 1
            pre = ''
        else:
            start_page = self.current_page - self.plus
            if self.current_page <= self.plus * 2:  
                self.req.setlist('page',[1])
                pre = f'<span class="updown"><a href=?{self.req.urlencode()}>首页</a></span>'
            else:
                self.req.setlist('page', [self.current_page - self.plus * 2])
                pre = f'<span class="updown"><a href=?{self.req.urlencode()}>上一页</a></span>'
        
        if self.current_page >= self.page_count - self.plus:
            end_page = self.page_count
            behe=''
        else:
            end_page = self.current_page + self.plus
            if self.current_page >= self.page_count - self.plus * 2:
                self.req.setlist('page',[self.page_count])
                behe = f'<span class="updown"><a href=?{self.page_count}>尾页</a></span>'
            else:
                self.req.setlist('page',[self.current_page + self.plus * 2])
                behe = f'<span class="updown"><a href=?{self.req.urlencode()}>下一页</a></span>'

        # 在筛选好的数据基础上,点击2页时不会使得search条件失去效果
        page_string = ''
        page_string += pre
        for i in range(start_page, end_page + 1):
            self.req.setlist('page', [i])
            if i == self.current_page:
                page_string += f"<span style='background-color:#fff;'><a style='color:#000' href=?{self.req.urlencode()}>{i}</a></span>"
            else:
                page_string += f"<span><a href=?{self.req.urlencode()}>{i}</a></span>"
        page_string += behe
        page_string = mark_safe("".join(page_string))
        return page_string

5、使用封装好的分页搜索

from app02.utils.SplitPage import Splitpagenumber
def in5(request):
    data_dict={}
    search = request.GET.get('search')
    if search:
        data_dict['phone__contains'] = search
    queryset = models.User.objects.filter(**data_dict)
    page_obj = Splitpagenumber(request,queryset)#传递筛选好的数据
    data = page_obj.page_data
    page_string = page_obj.html()
    context={
        "search":search,
        "data": data,
        "page_string": page_string
    }
    return render(request,'in5.html',context)
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="{% static '/js/jquery-3.6.0.min.js' %}"></script>
    <style>
        @import "{% static 'css/tab.css' %}";
        *{
            padding: 0;
            list-style: none;
            margin: 0;
        }
        span{
            display: inline-block;
            width: 40px;
            text-align: center;
            font-size: 20px;
            border: 1px solid;
            background-color: #2aabd2;
        }
        a{
            text-decoration: none;
            color: white;
        }
        div{
            width: 1200px;
        }
        aside{
            width: 800px;
            margin: 0 auto;
        }
        .data{
            width: 300px;
            height: 225px;
            border: 1px solid #8a6d3b;
            margin-bottom: 30px;
        }
        .updown{
            display: inline-block;
            width: 80px;
        }
        .updown a{
            font-size: 15px;
            line-height: 20px;
        }
    </style>
</head>
<body>
<form method="get">
<input type="text" name="search" placeholder="{{ search }}"><button type="submit">搜索</button>
</form>
<hr style="margin-bottom: 10px;">
<table>
    <tr>
        <td>ID</td>
        <td>号码</td>
        <td>价格</td>
        <td>等级</td>
        <td>状态</td>
    </tr>
{#    插入数据条#}
    {% for i in data %}
        <tr>
            <td>{{ i.id }}</td>
            <td>{{ i.phone }}</td>
            <td>{{ i.price }}</td>
            <td>{{ i.level }}</td>
            <td>{{ i.get_status_display }}</td>
        </tr>
    {% endfor %}
</table>
<ul>
    {{ page_string }}
</ul>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1231901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java】volatile-内存可见性问题

1、什么是内存可见性问题&#xff1f; &#xff08;1&#xff09;实例 要明白什么是内存可见性&#xff0c;我们首先来看一段代码 public class demo1 {public static int isQuit 0;public static void main(String[] args) {Thread thread1 new Thread(()->{while (is…

【每日刷题——语音信号篇】

思考与练习 练习2.1 语音信号在产生的过程中&#xff0c;以及被感知的过程中&#xff0c;分别要经过人体的哪些器官&#xff1f; 1.产生过程&#xff1a; 肺部空气 → \rightarrow →冲击声带 → \rightarrow →通过声道&#xff08;可以调节&#xff09; → \rightarrow →…

【小呆的力学笔记】有限元专题之循环对称结构有限元原理

文章目录 1. 循环对称问题的提出2. 循环对称条件2.1 节点位移的循环对称关系2.2 节点内力的循环对称关系 3. 在平衡方程中引入循环对称条件 1. 循环对称问题的提出 许多工程结构都是其中某一扇面的n次周向重复&#xff0c;也就是是周期循环对称结构。如果弹性体的几何形状、约…

【洛谷 P3743】kotori的设备 题解(二分答案+递归)

kotori的设备 题目背景 kotori 有 n n n 个可同时使用的设备。 题目描述 第 i i i 个设备每秒消耗 a i a_i ai​ 个单位能量。能量的使用是连续的&#xff0c;也就是说能量不是某时刻突然消耗的&#xff0c;而是匀速消耗。也就是说&#xff0c;对于任意实数&#xff0c;…

java学习part06数组工具类

1比较内容 2输出信息 3值填充 4快速排序 5二分查找 负数没找到&#xff0c;其他表示下标

SVG圆形 <circle>的示例代码

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…

【MySql】13- 实践篇(十一)

文章目录 1. 自增主键为什么不是连续的&#xff1f;1.1 自增值保存在哪儿&#xff1f;1.2 自增值修改机制1.2.1 自增值的修改时机1.2.2 自增值为什么不能回退? 1.3 自增锁的优化1.3.1 自增锁设计历史 2. Insert语句为何很多锁?2.1 insert … select 语句2.2 insert 循环写入2…

记录--alova组件使用方法(区别axios)

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 在我们写项目代码时&#xff0c;应该更加专注于业务逻辑的实现&#xff0c;而把定式代码交给js库或工程化自动处理&#xff0c;而我想说的是&#xff0c;请求逻辑其实也是可以继续简化的。 你可能会说…

npm install 下载不下来依赖解决方案

背景 最近在构建 前端自动化部署 的方案中发现了一个问题&#xff0c;就是我在npm install的时候&#xff0c;有时候成功&#xff0c;有时候不成功&#xff0c;而且什么代码也没发生更改&#xff0c;报错也就是那么几个错&#xff0c;所以在此也整理了一下遇到这种情况&#xf…

音视频同步笔记 - 以音频时间为基

音视频同步 - 以音频时间为基 上图介绍&#xff1a; 该图是以音频的时间为基&#xff0c;对视频播放时间的延迟控制方案&#xff0c;只调整视频的播放延时。delayTime是视频播放的延迟时间&#xff0c;初始值是1 / FPS * 1000 (ms)&#xff0c;如果FPS为25帧率&#xff0c;初始…

MySQL 备份和恢复

目录 一.MySQL数据库的备份的分类 1.1.数据备份的重要性 1.2.数据库备份的分类和备份策略 1.3.常见的备份方法 二.MySQL完全备份 2.1.什么是完全备份 2.2.完全备份的优缺点 2.3.实现物理冷备份与恢复 1&#xff09;实现流程 2&#xff09;前置准备 3&#xff09;实现…

Shell判断:模式匹配:case(一)

一、前言 shell编程中if和case都是用来做流控的。 二、case语法结构 case 变量 in 模式1&#xff09; 命令序列1 ;; 模式2&#xff09; 命令序列2 ;; 模式3&#xff09; 命令序列3 ;; *) 无匹配…

共享内存和信号量的配合机制

进程之间共享内存的机制&#xff0c;有了这个机制&#xff0c;两个进程可以像访问自己内存中的变量一样&#xff0c;访问共享内存的变量。但是同时问题也来了&#xff0c;当两个进程共享内存了&#xff0c;就会存在同时读写的问题&#xff0c;就需要对于共享的内存进行保护&…

数据结构--串的基本概念

目录 串的基本概念 串的定义 串与线性表对比 ​串的基本操作​ 串的比较 字符集编码 乱码问题​编辑 总结 ​串的存储结构 ​串的顺序存储​编辑 串的链式存储 串的基本操作 1、求字串 2、比较 3、定位操作 总结 串的基本概念 串的定义 串与线性表对比 串的…

无障碍功能更新,帮助残障人士轻松快捷完成日常事务

作者 / Google Products for All 团队高级总监 Eve Andersson 我们将与您分享一些全新的无障碍功能和部分更新&#xff0c;帮助您更轻松快捷地完成日常任务&#xff0c;让您不费吹灰之力就能自拍、查询步行路线或上网搜索等。我们最近在 Android 14 和 Wear OS 4 中推出了 Look…

软件测试/测试开发/人工智能丨基于Spark的分布式造数工具:加速大规模测试数据构建

随着软件开发规模的扩大&#xff0c;测试数据的构建变得越来越复杂&#xff0c;传统的造数方法难以应对大规模数据需求。本文将介绍如何使用Apache Spark构建分布式造数工具&#xff0c;以提升测试数据构建的效率和规模。 为什么选择Spark&#xff1f; 分布式计算&#xff1a;…

clickhouse分布式之弹性扩缩容的故事

现状 社区不支持喔&#xff0c;以后也不会有了。曾经尝试过&#xff0c;难道是是太难了&#xff0c;无法实现吗&#xff1f;因为他们企业版支持了&#xff0c;可能是利益相关吧&#xff0c;谁知道呢&#xff0c;毕竟开源也要赚钱&#xff0c;谁乐意一直付出没有回报呢。 社区…

60 权限提升-MYMSORA等SQL数据库提权

目录 数据库应用提权在权限提升中的意义WEB或本地环境如何探针数据库应用数据库提权权限用户密码收集等方法目前数据库提权对应的技术及方法等 演示案例Mysql数据库提权演示-脚本&MSF1.UDF提权知识点: (基于MYSQL调用命令执行函数&#xff09;读取数据库存储或备份文件 (了…

ubuntu20.04蓝牙连接airpods

ubuntu20.04蓝牙连接airpods 解禁蓝牙安装blueman设置模式连接上没有声音的问题 解禁蓝牙 sudo rmmod btusb sleep 1 sudo modprobe btusb sudo /etc/init.d/bluetooth restart安装blueman sudo apt install blueman sudo apt-get install pulseaudio-module-bluetooth sudo …

Ajax基础(应用场景|jquery实现Ajax|注意事项)

文章目录 一、Ajax简介二、基于jquery实现Ajax三、使用Ajax注意的问题1.Ajax不要与form表单同时提交2.后端响应格式问题3、使用了Ajax作为请求后的注意事项 一、Ajax简介 AJAX&#xff08;Asynchronous Javascript And XML&#xff09;翻译成中文就是“异步Javascript和XML”。…