【Django】第二课 银行账户管理系统开发

news2025/2/2 2:54:33

概念

本文在上一篇文章基础之前进行构建和完善

账户信息的分页显示

用户通过点击首页的“查询账户”,进入账户信息查询页面

则点击该按钮触发点击事件,向django服务器发出请求

 

接着我们在urls.py中需要定义与该地址进行匹配的地址,并匹配后跳转至views.py文件中执行对应该功能的方法

 

 views.py

# 创建方法,用于从数据库中查询出所有的账户信息
# 将所有信息发送给展示列表信息的页面
def getAccountList(request):
    #当前要显示第几页的数据,由用户决定
    #获得用户使用get请求发送过来的页码参数
    # 对获得页码参数的代码进行捕获异常
    try:
        ym = request.GET["ym"]
    except:
        # 只要以上代码报错,那么就会执行这里面的代码
        # 上面的代码报错的原因是因为没有获得ym这个参数
        # ym默认设置为1
        ym=1
    # 查询Account表中所有数据,将数据转换成字典的格式
    accounts=Account.objects.all().values()
    # [
    # {'id': 1, 'password': '666666',
    # 'name': '马云', 'personId': '360105197204171611',
    # 'blance': 2000.12, 'openDate': '2022-10-20'},
    # {'id': 2, 'password': '888888',
    # 'name': '雷军', 'personId': '360105197807181615',
    # 'blance': 61235.78, 'openDate': '2021-12-10'},
    # {'id': 3, 'password': '999999',
    # 'name': '马斯克', 'personId': '360105198010181604',
    # 'blance': 548976.11, 'openDate': '2018-1-16'}
    # ]
    # 创建分页器对象,
    # 第一个参数表示从数据库中查询出来的总数据
    # 第二个参数表示设置每页显示多少条数据
    p=Paginator(accounts,10)
    # 从分页器中根据当前页码来获得当前页的对象
    page=p.get_page(ym)
    #从当前页对象中获得出数据列表
    accounts=page.object_list
    # 获得所有分页的总页数的迭代器
    yms=p.page_range
    return render(request,"accountList.html",{"accounts":accounts,"page":page,"yms":yms})

根据该代码,可理解,通过浏览器给定页码,进行获取对应的页码的列表数据发送给浏览器上进行展示,如果浏览器未指定页码,则服务器默认获取第一页的数据发送给浏览器,因此我们需要创建展示列表信息的html页面,其代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>账户信息列表页面</title>
    <style type="text/css">
        table{
            border-width: 0px;
            background-color: cadetblue;
            padding: 10px;
            width: 900px;
            text-align: center;
            border-radius: 10px;
            clear: right;
        }
        input{
            width: 60px;
            padding: 5px;
            border-width: 0px;
            border-radius: 5px;
            color: white;
        }
        input.btn_up{
            background-color: #4bede4;
        }
        input.btn_del{
            background-color: #ff5860;
            float: right;
            margin-bottom: 10px;
            width: 100px;
        }
        input.btn_up:hover{
            background-color:#16DCED ;
        }
        input.btn_del:hover{
            background-color: #FF1719;
        }
        td{
            padding: 5px;
        }
        #nav{
            width: 900px;
            height: 40px;
            margin-top: 10px;
        }
        a{
            text-decoration: none;
            margin: 3px;
            background-color: cadetblue;
        }
        a:hover{
            background-color: #FF1719;
        }

        a.c_page{
            background-color: #FF1719;
        }
        a.up_page,a.do_page{
            width: 80px;
            height: 40px;
            padding: 5px 10px;

            border-radius: 5px;
            color: white;
        }
        a.p_page{
            width: 40px;
            height: 40px;
            padding: 3px;
            border-radius: 5px;
            color: white;
        }

    </style>
    <script type="text/javascript">
        //定义方法,当用户点击某一条数据的修改按钮,触发点击事件
        //将该修改按钮对应的账号信息获取过来
        function getId(id) {
            //alert("获得的id为:"+id)
            //将账号发送给服务器,让服务器把账号作为条件查询数据库
            //从数据库中将该账号对应的用户的账户信息全部查询出来
            //发送给修改页面上进行显示,供用户修改
            //将获得的id通过http的get请求将数据以键值对的形式拼接在访问地址的后面以?隔开
            location.href="/getAccountById?id="+id;
        }
        //定义方法,用户点击全选按钮的时候,触发该方法
        function c_all(obj) {
            //obj:是全选按钮标签的对象
            //先判断当前状态是选中还是未选中
            //如果当前状态是未选中状态,状态要变为选中
            //如果当前状态是选中状态,状态要变为未选中状态
            //通过class选择器为cb的条件获得数据行上的所有多选按钮
            cbs=document.getElementsByClassName("cb");
            for (let i = 0; i <cbs.length ; i++) {
                cbs.item(i).checked=obj.checked;
            }
        }
        //定义方法,当反选按钮被点击,数据行中的原本选中的变为未选中,原本未选中的变为选中的
        function c_no() {
            cbs=document.getElementsByClassName("cb");
            for (let i = 0; i <cbs.length ; i++) {
                cbs.item(i).checked=!cbs.item(i).checked;
            }
        }
        //定义方法,当用户点击删除按钮,弹出提示对话框,提示用户是否需要删除选中的数据
        //如果要删除,检测所有数据行中哪些多选按钮被选中了
        //获得这个多选按钮同一个行中的账号id
        function btn_del() {
            //获得所有数据行中的多选按钮
            cbs=document.getElementsByClassName("cb");
            tds=document.getElementsByClassName("td_id")
            str="";
            for (let i = 0; i <cbs.length ; i++) {
                //判断每一条数据中哪些多选按钮是选中状态
                if (cbs.item(i).checked) {
                    //获取所有被勾选上的数据的账号id
                    var id=tds.item(i).innerHTML;
                    str+=id+","
                }
            }
            //设置确定对话框
            result=window.confirm("您是否确定要删除当前选中的账户?");
            if (result){
                location.href="/deleteById?ids="+str;
            }
        }
        
        //定义方法,用于处理分页导航栏的样式
        function a_style() {
            //通过class选择器获得分页导航栏对象
            var aElements=document.getElementsByClassName("p_page");
            for (var i = 0; i < aElements.length; i++) {
                var text=aElements.item(i).innerHTML;
                if (text<10){
                    aElements.item(i).innerHTML="&nbsp;"+text+"&nbsp;";
                }
            }
        }
    </script>
</head>
<body onload="a_style()">
    <div align="center" style="width: 900px;margin: auto">
        <h1>账户信息列表</h1>
        <p><input type="button" class="btn_del" onclick="btn_del()" value="删除"></p>
        <table>
            <tr>
                <th width="190px"><input type="checkbox"  onclick="c_all(this)">全选<input type="checkbox" onclick="c_no()">反选</th>
                <th>账号</th>
                <th>密码</th>
                <th>姓名</th>
                <th>身份证号</th>
                <th>余额</th>
                <th>开户日期</th>
                <th>操作</th>
            </tr>
            {% for account in accounts %}
            <tr>
                <td width="190px"><input type="checkbox" class="cb"></td>
                <td class="td_id">{{ account.id }}</td>
                <td>{{ account.password }}</td>
                <td>{{ account.name }}</td>
                <td>{{ account.personId }}</td>
                <td>{{ account.blance }}</td>
                <td>{{ account.openDate }}</td>
                <td>
                    <input type="button" class="btn_up" onclick="getId({{ account.id }})"   value="修改">
                </td>
            </tr>
            {% endfor %}
        </table>
    <!-- 显示页码导航栏 -->
    <div id="nav" align="center">
        <!-- 上一页 -->
        <!-- 判断当前页是否有上一页,如果有上一页则显示上一页的按钮,否则就不显示上一页 -->
        {% if page.has_previous %}
            <a href="/Accounts/?ym={{ page.previous_page_number }}" class="up_page">上一页</a>
        {% endif %}
        <!-- 页码 -->
        {% for ym in yms %}
            {% if page.number == ym %}
                <a href="/Accounts/?ym={{ ym }}" class="p_page c_page">{{ ym }}</a>
            {% else %}
                <a href="/Accounts/?ym={{ ym }}" class="p_page">{{ ym }}</a>
            {% endif %}
        {% endfor %}

        <!-- 下一页 -->
        {% if page.has_next %}
            <a href="/Accounts/?ym={{ page.next_page_number }}" class="do_page">下一页</a>
        {% endif %}
    </div>
    </div>
</body>
</html>

最终通过点击查询账户按钮,可查看到以下效果:

该页面的分页效果类似于百度网站的分页效果,这里供读者进行学习和参考,如果读者有更好的效果,可在本代码基础上进行完善。

批量删除以及全选和反选删除功能

在该列表展示页面中,我们也需要完成对于数据的批量删除功能,在前端页面上完成全选和反选供的代码是通过javascript的方式实现的,读者可通过学习html代码中的功能,结合运行的效果进行学习和理解。

当用户勾选在需要删除的账户信息后,点击删除后的同时,我们这里将选中的账户信息的主键id拼接成字符串以逗号隔开的方式作为参数使用get请求发送给服务器

我们在服务器中urls.py文件中定义接收的地址

 

views.py文件中进行数据解析和分解,完成删除

# 创建方法,接收页面上用户想要删除的数据对应的账号
def deletes(request):
    # 1,3,5,7,9,
    ids=request.GET["ids"]
    # 将字符串按逗号进行分割
    list1=str(ids).split(",")
    for id in list1:
        # 判断每一次循环的数据是否是数字
        if id.isdigit():
            # 将该id作为条件删除数据库的数据
            ac=Account.objects.get(id=id)
            ac.delete()
    return redirect(getAccountList)

 从数据库中删除完成后,我们需要立即刷新列表,进行数据库和浏览器页面的同步显示

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

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

相关文章

Java on VS Code 12月更新年度亮点回顾|实时内存视图、注入处理器支持与用户体验改进

作者&#xff1a;Nick Zhu - Senior Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;一年的时间过得很快&#xff0c;我们已经来到了2022年的年底。回顾 2022 年&#xff0c;我们的产品也经历了很多的迭代&#xff0c;在此之中…

甲氧基聚乙二醇二苯并环辛烯mPEG-DBCO简介DBCO-mPEG科研实验用试剂

中文名&#xff1a;甲氧基聚乙二醇二苯并环辛烯 英文名&#xff1a;mPEG-DBCO&#xff1b;DBCO-mPEG 分子量: 1K.2K.5K.10k.20k.30k 溶解度: DMSO, DMF 储存条件: -20C 状态&#xff1a;淡黄色到白色固体&#xff0c;或者半固体&#xff0c;取决于分子量。 溶解性&#x…

网心科技马婷:探寻边缘计算的“诗和远方”

​​LiveVideoStackCon 2022上海站活动结束&#xff0c;每一次大会的举办对音视频领域都是新的洗礼&#xff0c;同时也带来了新的收获和挑战。随着音视频技术在各种行业、场景中的逐渐成熟&#xff0c;更多的业务形态、产品变换 、跨界案例等越来越多的部分值得我们探寻和研究。…

「网络工程师必会技能」-路由器介绍和路由器基本配置

「网络工程师必会技能」-路由器介绍和路由器基本配置&#xff0c;这是每个网络必须会的技能&#xff0c;不是你有证书就一个网络工程师了哦&#xff01; 以Cisco路由器为例说明&#xff1a; &#xff08;1&#xff09;访问路由器。访问路由器与访问交换机一样&#xff0c;可以…

医院陪护小程序,专业的事情交给专业的人

陪诊服务这几年一直受到人们的好评&#xff0c;有了医院陪护小程序之后一些无法居家照顾老人的子女可以通过小程序为老人预约服务&#xff0c;陪诊平台的出现还让陪诊员有了正规的接单平台&#xff0c;不仅方便了人们下单找陪诊员还可以对陪诊人员坐正规的管理。那么在开发医院…

33.前端笔记-CSS3-2D转换

目录1、转换2、二维坐标系2.1 2D转换之移动translate2.2 2D旋转之rotate练习1练习2练习32.3 2D转换之缩放scale练习1练习22D转换综合写法转换综合练习1、转换 转换transform是CSS3中具有颠覆性的特征之一&#xff0c;可以实现元素的位移、旋转、缩放等效果 2、二维坐标系 2.…

Fabric.js 修改画布交互方式到底有什么用?

本文简介 点赞 关注 收藏 学会了 fabric.js 为我们提供了很多厉害的方法。今天要搞明白的一个东西是 canvas.interactive 。 官方文档对 canvas.interactive 的解释是&#xff1a; Indicates that canvas is interactive. This property should not be changed. canvas.in…

FPU与VFP最全面解释

本文希望能将FPU以及ARM中的FPU介绍清楚。 1. FPU&#xff08;Floating-Point Unit&#xff09; 浮点运算单元是处理器内部用于执行浮点数计算的逻辑部件&#xff0c;或者说硬件电路。不是所有的处理器都有该功能。浮点运算满足IEEE 754的标准&#xff0c;所谓IEEE 754标准&a…

关于Linux的动静态库

文章目录什么是动静态库生成静态库生成发布生成动态库发布使用库使用静态库查看系统头文件路径查看系统库文件路径使用库文件和头文件指定路径搜索头文件卸载库使用动态库动态库的运行搜索路径什么是动静态库 静态库&#xff08;.a&#xff09;&#xff1a;程序在编译链接的时…

再携手,齐并进!菊风助力宁波银行坐席PUSH外呼项目

随着“金融数字化”逐步成为金融行业的新浪潮&#xff0c;运用更加灵活的触达手段提升营销效果&#xff0c;促成业务闭环愈发成为银行业等金融机构角逐数字化转型成功的关键。 在此背景下&#xff0c;金融机构对于实时音视频技术的应用也从普遍的「呼入」需求逐步扩展到创新的…

LinkedHashSet源码解析

LinkedHashSet源码解析 问题 &#xff08;1&#xff09;LinkedHashSet 的底层使用什么存储元素&#xff1f; &#xff08;2&#xff09;LinkedHashSet 与 HashSet 有什么不同&#xff1f; &#xff08;3&#xff09;LinkedHashSet 是有序的吗&#xff1f; &#xff08;4&a…

Vue2与Vue3 setup的使用差异与对比

最近一直在做vue2的技术栈升级&#xff0c;于是心血来潮&#xff0c;就想要不写篇文章总结一下vue2和vue3在使用上的不同吧&#xff0c;于是乎&#xff0c;我们这就开始吧&#xff01; 首先说明一下&#xff0c;vue3有多种写法&#xff0c;本文使用setup语法糖&#xff0c;不考…

硬核!Github 星标 79.4K 的阿里强推 Java 面试参考指南到底有多强?

谈到 Java 面试&#xff0c;相信大家第一时间脑子里想到的词肯定是金三银四&#xff0c;金九银十。好像大家的潜意识里做 Java 开发的都得在这个时候才能出去面试&#xff0c;跳槽成功率才高&#xff01;但 LZ 不这么认为&#xff0c;LZ 觉得我们做技术的一生中会遇到很多大大小…

组件技术--设计--jsp+servlet+bean+MySQL 简单的登录注册案例

JavaBeanMySQLjspservlet 简单的登录注册案例登录注册案例需求核心系统组成Javaweb项目框架基本思想BeancounterUserDaoUserDaoservletLoginCljspindex.jspLoginServlet.jspregister.jspregisterMessage.jspwelcome.jsptargetpom.xmlWEB-INFweb.xml登录注册案例需求 本项目利用…

【论文阅读笔记】CycleISP: Real Image Restoration via Improved Data Synthesis

论文地址&#xff1a;https://arxiv.org/abs/2003.07761 代码地址&#xff1a;https://github.com/swz30/CycleISP 论文小结 总的来说&#xff0c;就是现实世界中无法获取有效的图像对。且之前合成噪声的方式是在sRGB上添加高斯白噪声&#xff0c;但对于相机传感器成像管道来说…

工控CTF之协议分析7——OMRON

协议分析 流量分析 主要以工控流量和恶意流量为主&#xff0c;难度较低的题目主要考察Wireshark使用和找规律&#xff0c;难度较高的题目主要考察协议定义和特征 简单只能简单得干篇一律&#xff0c;难可以难得五花八门 常见的工控协议有&#xff1a;Modbus、MMS、IEC60870、…

同源策略跨域

目录1.同源策略限制的意义1.请求协议 均为 http2.主机此这为 localhost3.端口号不同 一个 8080 一个 50002.注意3.解决跨域代理服务器 80801.同源策略限制的意义 让前端发送的请求不能随意访问其他端口的服务器&#xff0c;一定程度保护服务器和用户的隐私 1.请求协议 均为 …

nexus上传jar包

nexus上传自定义starter1、普通jar包和springboot的starter1.1、starter上传简介1.2、上传方法2.1.1、setting.xml文件2.1.2、项目中的pom文件1.3、具体部署2、父pom文件上传这里我们主要讲解两种&#xff0c;一种是jar包上传&#xff0c;包含普通jar包和springboot的starter包…

jmeter简单压力测试

测试目的&#xff1a;10个用户并发访问一个接口&#xff08;http://127.0.0.1:8080/dfm/login.action&#xff09;&#xff0c;能否正常响应。 一、打开JMeter 二、右击“测试计划”&#xff0c;添加线程组 三、设置线程组的线程数 JMeter中的线程组&#xff0c;类似于LoadRunn…

RCTFweb复现

文章目录filechecker_minieasy_uploadfilechecker_plusfilechecker_pro_maxezbypassezruoyifilechecker_mini 给了附件&#xff0c;代码比较短&#xff0c;先审计一下。 在这里发现了file –b命令&#xff0c;且filepath部分可控&#xff0c;明显的ssti漏洞&#xff0c;没过…