◢Django 自写分页与使用

news2024/12/30 3:49:40

目录

1、设置分页样式,并展示到浏览器

 2、模拟页码

 3、生成分页

4、数据显示

 5、上一页下一页

6、数据库的数据分页

 7、封装分页

8、使用封装好的分页

建立好app后,设置路径path('in2/',views.in2),视图def in2(request): ,HTML: in2.html

1、设置分页样式,并展示到浏览器

def in2(request):
    return render(request,'in2.html')
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            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;
        }
    </style>
</head>
<body>
    <span><a>1</a></span>
</body>
</html>

 2、模拟页码

def in2(request):
    # 假设有100条数据
    data_count = 100 #350
    #每页有8条数据
    page_size = 8
    #共有多少页
    page_count, count=divmod(data_count,page_size)
    if count:
        page_count+=1

    page_string = ''
    for i in range(page_count):
        page_string+=f"<span><a>{i}</a></span>"
        
    #page_string = mark_safe("".join(page_string))
    return render(request,'in2.html',{"page_string":page_string})

若是在html中直接导入page_string 那就是一个字符串,

需要将循环生成的page_string进行,【取消注释】

page_string = mark_safe("".join(page_string))

作用是:将字符串列表(`page_string`)中的元素连接起来,并将结果标记为安全的HTML内容。使用`join()`函数将字符串列表中的所有元素连接在一起,然后`mark_safe()`函数将连接起来的字符串标记为安全的,这样在显示HTML内容时,就不会对其中的标签和特殊字符进行转义处理。通常用于在模板中生成动态的HTML内容,以避免对HTML标签和特殊字符进行转义。

 3、生成分页

数据量增多后,页码就变多了,需要设置显示的分页,在当前页的基础上显示前5页后5页,多出的页码不显示

为每个a标签附带参数page,使用字符串拼接,用for循环标明每个a所附带的参数,

点击a标签,发送的是get请求,GET请求没有获得page时,默认为第一页,点击之后,url自动携带page参数,每次点击获取该a标签的携带page参数,用作当前页

def in2(request):
    #默认设置当前页为1,若有get请求传递过来的当前页,则进行更改
    
    if request.GET.get('page'):
        current_page = int(request.GET.get('page'))
    else:
        current_page = 1

    data_count = 350    
    page_size = 8   
    page_count, count=divmod(data_count,page_size)  
    if count:
        page_count+=1


    #设置当前页的前后可见页数为5
    plus = 5
    #当前页小于等于5 起始页始终为1 ;当前页大于5 起始页为当前页减5
    if current_page <= plus + 1:
        start_page = 1
    else:
        start_page = current_page - plus
    # 当前页大于等于最终点页 结束页始终为终点页 ;当前页小于终点页减5 结束页为当前页+5
    if current_page >= page_count - plus:
        end_page = page_count
    else:
        end_page = current_page + plus


    page_string = ''
    for i in range(start_page, end_page + 1):
        page_string += f"<span><a href=?page={i}>{i}</a></span>"

    page_string = mark_safe("".join(page_string))
    context={
        "current_page":current_page,
        "start_page":start_page,
        "end_page" :end_page,
        "page_string":page_string,
    }
    return render(request,'in2.html',context)

成功后,为了显示当前页的不同,需要在for循环那里,增加一个if,用以判断,i与当前页是否相同,相同则为该页加上不同的样式

for i in range(start_page, end_page + 1):
    if i == current_page:
        page_string += f"<span style='background-color:#fff;'><a style='color:#000' href=?page={i}>{i}</a></span>"
    else:
        page_string += f"<span><a href=?page={i}>{i}</a></span>"

4、数据显示

增加数据的时候,注意最后一页数据是不满的[44*8=352],一共有350条数据,所以最后一页的end为总数据条数。

#获取数据的起始位置与结束位置[1,8],[9,16]
start = int(current_page - 1 ) * page_size + 1
if current_page == page_count:#当前页是最后一页时,数据并不是8条数据
        end = data_count
else:
        end = int(current_page) * page_size
print(start,end)

给context字典中补充起始数据,与结束数据,这里采用的是整型数字用来模拟数据总数,在HTML中for不能同平时使用,不能迭代整型数据,直接传入range(start,end,step)作为迭代器

context={

        "data":range(start,end+1),

}

 在HTML中遍历data

<style>
.data{
      width: 300px;
      height: 166px;
      border: 1px solid #8a6d3b;
      margin-bottom: 30px;
}
</style>

<body>
<div class="data">
    {% for i in data %}
        <li>这是第 {{ i }} 条数据</li>
    {% endfor %}
</div>
</body>

                            

 5、上一页下一页

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

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

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

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

# 上一页,下一页
 if current_page <= plus +1:#当前页在前5页时,不需要上一页
     pre = ''
 else:
     if current_page <= plus * 2 :#当前页处于5-10页时,点击上一页,跳转到第1页
         pre=f'<span class="updown"><a href=?page={1}>首页</a></span>'
     else:
         pre = f'<span class="updown"><a href=?page={current_page - plus * 2}>上一页</a></span>'
 if current_page >= page_count - plus:
     next = ''
 else:
     if current_page >= page_count - plus * 2:
         next = f'<span class="updown"><a href=?page={page_count}>尾页</a></span>'
     else:
         next = f'<span class="updown"><a href=?page={current_page + plus * 2}>下一页</a></span>'

整合分页和上下页的程序,减少if的判断

6、数据库的数据分页

605/8=75,605%8=5【最后一页是75,有5条数据】第一列是表的id不是序号,中间有删掉的id,所以最终值不为605

data_count =  models.表名.objects.all().count()

<div class="data">
    {% for i in data %}
        <li><span>{{ i.id }}</span> <span style="width: 130px">{{ i.phone }}</span> <span>{{ i.price }}</span></li>
    {% endfor %}
</div>

 

在 SQL Server 中,索引是从 1 开始计数的,需要 +1,而MySql数据库的索引是从0开始,所以不用加,注意区别自己使用的数据起始索引  

 7、封装分页

建立软件包,命名为utils

 在utils中建立SplitPage.py,整合前面程序,该封装的封装,该方法体的方法体,page_size不写默认为8,写则加载

from django.utils.safestring import mark_safe
class Splitpagenumber:
    def __init__(self,request, queryset, page_size=8, plus=5, ):
        #定义变量,方法体实现分页
        if request.GET.get('page'):
            self.current_page = int(request.GET.get('page'))
        else:
            self.current_page = 1
        #数据库,
        self.queryset = queryset
        self.data_count = queryset.count()#数据总条数

        self.page_size = page_size
        '''可分为多少个页码'''
        self.page_count,self.count = divmod(self.data_count, page_size)
        if self.count:
            self.page_count += 1

        start = int(self.current_page - 1) * page_size
        if self.current_page == self.page_count:  # 当前页是最后一页时,数据并不是8条数据
            end = self.data_count
        else:
            end = int(self.current_page) * page_size

        self.data = self.queryset[start:end]
        self.plus =plus



    def html(self):

        # 获取数据的起始位置与结束位置[0,8],[
        start = int(self.current_page - 1) * self.page_size
        if self.current_page == self.page_count:  # 当前页是最后一页时,数据并不是8条数据
            end = self.data_count
        else:
            end = int(self.current_page) * self.page_size
        print(start, end)
        data = self.queryset[start:end]
        #实现 起始页,结束页 ,与 上一页下一页
        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:  # 当前页处于5-10页时,点击上一页,跳转到第1页
                pre = f'<span class="updown"><a href=?page={1}>首页</a></span>'
            else:
                pre = f'<span class="updown"><a href=?page={self.current_page - self.plus * 2}>上一页</a></span>'
        # 当前页大于等于最终点页 结束页始终为终点页 ;当前页小于终点页减5 结束页为当前页+5
        if self.current_page >= self.page_count - self.plus:
            end_page = self.page_count
            next = ''
        else:
            end_page = self.current_page + self.plus
            if self.current_page >= self.page_count - self.plus * 2:
                next = f'<span class="updown"><a href=?page={self.page_count}>尾页</a></span>'
            else:
                next = f'<span class="updown"><a href=?page={self.current_page + self.plus * 2}>下一页</a></span>'
        """ 生成html格式 """
        page_string = ''
        page_string += pre

        for i in range(start_page, end_page + 1):
            if i == self.current_page:
                page_string += f"<span style='background-color:#fff;'><a style='color:#000' href=?page={i}>{i}</a></span>"
            else:
                page_string += f"<span><a href=?page={i}>{i}</a></span>"

        page_string += next
        page_string = mark_safe("".join(page_string))

        return page_string

8、使用封装好的分页 

完善in3的路径联系,然后运行in3

from app02.utils import SplitPage
def in3(request):
    queryset = models.User.objects.all()
    page_object = SplitPage.Splitpagenumber(request, queryset)
    context={
        "info":page_object.data,
        "page_string":page_object.html()
    }
    return render(request,'in3.html',context)

默认分页 【数据显示添加css】

page_object = SplitPage.Splitpagenumber(request, queryset,page_size=31,plus=5)
page_object = SplitPage.Splitpagenumber(request, queryset,page_size=2,plus=10)

只截了最后一页,分页显示的就不一样,但数据相同 

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

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

相关文章

web自动化框架之四测试报告的搭建

现状&#xff1a; 看过前面的文章&#xff0c;楼主用的是python&#xff0c;所以在搭建测试报告这块的时候使用的是unittesthtmlTestRunner&#xff1b;然后发现生成出来的报告&#xff0c;总是有那么不完美的地方&#xff0c;比如想增加图片&#xff0c;比如显示风格改变下&a…

GPU Microarch 学习笔记【2】Unified Memory

目录 1. M3 Dynamic Caching 2. Unified Memory 3. Unified Memory是如何处理page fault的 4. Unified Memory Page Fault的相关论文 M3 Dynamic Caching 最新的Apple M3 芯片最亮眼的可能是支持dynamic caching&#xff0c;如下图所示。 具体说来就是传统的GPU分配内存时&…

北邮22级信通院数电:Verilog-FPGA(9)第九周实验(1)实现带同步复位功能、采用上升沿触发的D触发器

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.顶层模块的书写 二.两种验证方法 2.1使用…

美国BGP服务器有哪些优势?

​  在当今数字化时代&#xff0c;网络连接的性能和可靠性对于企业和个人来说至关重要。而美国作为全球互联网的中心之一&#xff0c;其地区BGP服务器拥有许多优势。  网络性能和可靠性&#xff1a;美国BGP专线服务器采用BGP协议&#xff0c;一种高级动态路由协议&#xff…

线性表->栈

文章目录 前言概述栈的初始化销毁压栈出栈判断栈为不为空栈的有效个数 前言 栈相对于链表&#xff0c;稍微简单一点&#xff0c;但是栈的难点在于通过栈去理解递归算法。 概述 **栈&#xff1a;**一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。…

FreeRTOS知识梳理

一、RTOS:Real time operating system,中文意思为 实时操作系统&#xff0c;它是一类操作系统&#xff0c;比如uc/OS、FreeRTOS、RTX、RT-Thread 这些都是实时操作系统。 二、移植FreeRTOS到STM32F103C8T6上 interface选择CMSIS_V1,RCC选择Crystal Ceramic Resonator 。 …

【2012年数据结构真题】

41题 &#xff08;1&#xff09; 最坏情况下比较的总次数 对于长度分别为 m&#xff0c;n 的两个有序表的合并过程&#xff0c;最坏情况下需要一直比较到两个表的表尾元素&#xff0c;比较次数为 mn-1 次。已知需要 5 次两两合并&#xff0c;故设总比较次数为 X-5, X 就是以 N…

Django(四、路由层)

文章目录 一、路由层1.路由匹配url方法第一个是参数 的正则表达式 二、正则无名分组与有名分组无名分组有名分组 三、反向解析1.概念无名分组动态路由解析有名分组动态路由解析 四、路由分发为什么要用路由分发&#xff1f; 1.总路由分发配置名称空间 五、伪静态的概念六、虚拟…

【STM32 CAN】STM32G47x 单片机FDCAN作为普通CAN外设使用教程

STM32G47x 单片机FDCAN作为普通CAN外设使用教程 控制器局域网总线&#xff08;CAN&#xff0c;Controller Area Network&#xff09;是一种用于实时应用的串行通讯协议总线&#xff0c;它可以使用双绞线来传输信号&#xff0c;是世界上应用最广泛的现场总线之一。CAN协议用于汽…

基于SSM+Vue的网上购物商城

基于SSMVue的网上购物商城的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringMyBatisSpringMVC工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 商品详情 登录界面 管理员界面 用户界面 可视化图标 摘要 基于SSM&#xff0…

vcomp120.dll丢失怎么办?vcomp120.dll丢失的解决方法分享

vcomp120.dll丢失”。这个错误通常会导致某些应用程序无法正常运行&#xff0c;给用户带来困扰。那么&#xff0c;当我们遇到这个问题时&#xff0c;应该如何修复呢&#xff1f;下面我将为大家介绍四个修复vcomp120.dll丢失的方法。 一、使用dll修复程序修复 可以通过百度或许…

Knife4j在springboot3中如何集成呢(如果大家阅读能力好的话,建议直接看作者写的博客。当然,在下面也会附上作者的博客)

一.为什么会写这篇博客呢&#xff1f; 因为本作者在使用springboot2的时候还好好的&#xff0c;将springbooot2升到springboot3的时候&#xff0c;发现我天&#xff0c;knife4j好像出问题了&#xff0c;找了好久才发现时knife4j的版本问题。 二.说一下knife4j的版本问题吧&…

力扣刷题-二叉树-二叉树的层序遍历(相关题目总结)

思路 层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。 需要借用一个辅助数据结构即队列来实现&#xff0c;队列先进先出&#xff0c;符合一层一层遍历的逻辑&#xff0c;而用栈先进后出适合模拟深度优先遍历也就是递归的…

力扣刷题-二叉树-翻转二叉树

226.翻转二叉树 翻转一棵二叉树。 思路 参考&#xff1a; https://www.programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html#%E6%80%9D%E8%B7%AF 如果要从整个树来看&#xff0c;翻转还真的挺复杂&#xff0c;整个树以中间分割线进行翻转&#xf…

【CUDA编程--编程模型简介算子开发流程】

官方文档&#xff1a;https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html 什么是CUDA CUDA全称&#xff08;Compute Unified Device Architecture&#xff09;统一计算架构&#xff0c;是NVIDIA推出的并行计算平台深度学习加速&#xff1a;对于神经网络&…

超级干货:光纤知识总结最全的文章

你们好&#xff0c;我的网工朋友。 光纤已经是远距离有线信号传输的主要手段&#xff0c;而安装、维护光纤也是很多人网络布线的基本功。 在网络布线中&#xff0c;通常室外楼宇间幢与幢之间使用的是光缆&#xff0c;室内楼宇内部大都使用的是以太网双绞线&#xff0c;也有使用…

前端案例-css实现ul中对li进行换行

场景描述&#xff1a; 我想要实现&#xff0c;在展示的item个数少于4个的时候&#xff0c;则排成一行&#xff0c;并且均分&#xff08;比如说有3个&#xff0c;则每个的宽度为33.3%&#xff09;&#xff0c;如果item 个数大于4&#xff0c;则进行换行。 效果如下&#xff1a…

冰点还原精灵_Deep Freeze Standard v8.60.020.5592中文版

eep Freeze&#xff08;又被成为冰点还原精灵&#xff09;是Faronics公司出品的一款简单易用的系统还原软件&#xff0c;使用能够帮助用户轻松将系统还原到安装该款软件之后状态&#xff0c;避免因为病毒的入侵以及人为的对系统无意或无意的破坏&#xff0c;让你的系统始终完美…

HTTP——

HTTP 请求报文的构成 如下图: 第一行:HTTP请求的方法,具体是POST方法还是GET方法,或是其它方法;URI就是你的HTTP请求的路径;后面是HTTP协议的版本; 第二行往下连续多行:这些是请求头部分,也就是请求的首部设置的一些信息,相当于对HTTP请求的一些设置; 空格行:在…