Django(三、数据的增删改查、Django生命周期流程图)
文章目录
- 一、 基于ORM进行的CURD
- user_list:作为主页使用
- 路由文件urls.py配置如下:
- add.html:用于新增用户的数据页
- add页面视图函数如下:
- edit.html:修改数据的页面
- 那么来总结一下上序所操作所用到的内容。
- 导入已存在的表
- 其方式有两种
- 二、ORM外键关联
- Django请求的生命周期流程图
一、 基于ORM进行的CURD
本质上就是通过面向对象的方式,对数据库的数据进行增、删、改、查。
这里将会将我们之前所有内容结合到一起,首先确保基于上序操作已经建立好了UserInfo表,那么我们还需要建立几个HTML文件,只需要关注与提交数据有关的标签
user_list:作为主页使用
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body><div class="container"><div class="row"><div class="col-md-8 col-md-offset-2" ><h1 class="text-center">用户列表展示</h1><hr><a href="/add/" class="btn btn-info" >添加</a><table class="table table-striped table-bordered"><thread><tr><th class="text-center">ID</th><th class="text-center">username</th><th class="text-center">password</th><th class="text-center">gender</th><th class="text-center">action</th></tr></thread><tbody>{% for foo in user_obj %}<tr><td class="text-center" >{{ foo.id }}</td><td class="text-center" >{{ foo.username }}</td><td class="text-center" >{{ foo.password }}</td><td class="text-center" >{{ foo.gender }}</td><td><a href="/edit/?id={{ foo.id }}" class="btn btn-success" style="margin-left: 65px;">修改</a> <a href="/delete/?id={{ foo.pk }}" class="btn btn-danger ">删除</a></td></tr>{% endfor %}</tbody></table></div></div></div>
</body>
</html>
主页已经建立好了,现在我们需要配置路由文件urls.py。根据点击主页的按钮跳转的页面来配置路由。
路由文件urls.py配置如下:
如果前后端不是同一个人开发的话,这些url必须要提前规定好。
针对主页的视图函数
add.html:用于新增用户的数据页
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body><div class="container"><div class="row"><div class="col-md-8 col-md-offset-2"><h1 class="text-center">添加用户</h1><hr><form action="" method="post"><div class="form-group">username: <input type="text" class="form-control" name="username" placeholder="请输入用户名"></div><div class="form-group">password: <input type="password" class="form-control" name="password" placeholder="请输入密码"></div><div class="form-group">gender: <input type="text" class="form-control" name="gender" placeholder="请输入性别"></div><div class="form-group"><input type="submit" class="btn btn-block btn-success" value="提交"></div></form></div></div></div>
</body>
</html>
根据上面表单的action可以看出,数据是提交到原地提交post请求的。
add页面视图函数如下:
def add(request):if request.method == 'POST': # 接收用户增加数据发送的post请求username = request.POST.get('username')password = request.POST.get('password')gender = request.POST.get('gender')'数据库中添加数据的''操作数据库添加数据'add_obj=models.UserInfo.objects.create(username=username, password=password, gender=gender)'返回的是当前记录的对象'# print(add_obj) # jack# print(add_obj.gender) # malereturn redirect('/user_list/') # 重定向到主页return render(request, 'add.html', locals())
当原地提交post请求的数据会被我们当前视图函数接收到,然后再写入数据库内。
此时我们就可以从主页点击添加按钮,然后输入完毕后,来检验效果:
此时已经达到了数据同步到web页面的效果了,那么我们再来尝试修改。
edit.html:修改数据的页面
<!DOCTYPE html>
<html lang="en">
<head>{% load static %}<meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body><div class="container"><div class="row"><div class="col-md-8 col-md-offset-2"><h1 class="text-center">修改页面</h1><hr><form action="" method="post"><div class="form-group">username: <input type="text" class="form-control" name="username" value="{{ edit_obj.username }}"></div><div class="form-group">password: <input type="password" class="form-control" name="password" value="{{ edit_obj.password }}"></div><div class="form-group">gender: <input type="text" class="form-control" name="gender" value="{{ edit_obj.gender }}"></div><div class="form-group"><input type="submit" class="btn btn-block btn-success" value="提交"></div></form></div></div></div>
</body>
</html>
修改页面的套路基本和添加数据页面差不多,观察表单的提交地址是原地址,再根据input元素的name属性值在后端接收数据。
因为我们在user_list页面内定义了,点击修改按钮,URL地址中还会携带一个用户的id编号,那么我们需要接收这个编号,再根据它来修改用户信息。
def edit(request):edit_id = request.GET.get('id') # GET可以获取URL内,问号后面的数据if request.method == 'POST':username = request.POST.get('username')password = request.POST.get('password')gender = request.POST.get('gender')'''数据库中的修改字段语法update userinfo set username='', password='' where id=1;'''# 第一种方式models.UserInfo.objects.filter(pk=edit_id).update(username=username,password=password,gender=gender)使用update这种语句方法不需要save保存# 第二种方式edit_obj = models.UserInfo.objects.filter(id=edit_id).first() # 获取这个用户对象edit_obj.username = username # 修改这个用户的姓名edit_obj.password = password # 修改这个用户的密码edit_obj.gender = gender # 修改性别edit_obj.save() # 将修改后的数据保存到数据库return redirect('/user_list/')return render(request, 'edit.html', locals())
删除自然就不需要什么页面了,在主页点击后就会跳转到一个URL执行一个视图函数,并且这个URL内携带用户的编号,那么基本操作套路就是一样了。
def delete(request):del_id = request.GET.get('id')print(del_id)'''数据库中删除字段语法delete from userinfo where id = 1;'''models.UserInfo.objects.filter(pk=del_id).delete() # 删除数据库内,和页面传递过来相同编号的用户return redirect('/user_list/') # 重定向到主页,达到一个刷新的效果
已经达到了我们预期的效果,点击一下删除按钮整行数据。
那么来总结一下上序所操作所用到的内容。
1.查models.User.objects.filter(name=username, pwd=password)如何获取对象 可以使用first()方法 如果没有值会返回None 我们if判断即可obj = User.object.get(id=edit_id) # 获取一个用户对象print(obj.name) # 查询这个用户的name值2.增方法一:models.User.objects.create(name='jack',password=123)# 向数据库写入一条记录,name字段值为jack,password字段值为123方法二:obj = models.User(username=username,password=password,gender=gender)obj.save()3.改方法一:models.User.objects.filter(id=1).update(name='tom')方法二:obj = models.User.objects.filter(id=1).first()obj.name = 'tom' # 修改这个用户的name属性值obj.age = 18 # 修改这个用户的age属性值obj.save() # 将修改后的属性值,同步到数据库4.删models.User.objects.filter(id=1).delete() # 在数据库内删除这个用户5.获取所有用户对象obj_all = User.object.all()也可以用获取局部所有变量的方法locals()6.获取指定一个对象obj = User.object.filter('id').first()'filter类比数据库中where的使用'
至此已经完成了基本操作,可以通过面向对象的形式来操作数据库里面的数据,但前提是模型类是已经存在的数据库表,如果不存在则当我们执行迁移时,Django帮助我们自动创建。
那么如果要导入已经存在的表到我们的模型里面呢。那么我们来了解一下吧!
导入已存在的表
在Django内操作数据库是通过模型models.py里面的类,而我们目前只了解怎么通过它创建数据库表,而没有了解过如何使用它导入已经存在数据库内的表。
其方式有两种
在模型内,按照表的完整数据结构创建类名、类属性,整体代码如下:
class Book(models.Model):name = models.CharField(max_length=30, blank=True, null=True)price = models.FloatField(blank=True, null=True)author = models.CharField(max_length=20, blank=True, null=True)class Meta:db_table = 'book'
会发现多出来一个Meta内部类,其作用我们目前不深究,知道此时它的作用即可:通过db_table属性,指定模型类对应的数据库表名。
偷懒方式:通过Django自带的命令inspectdb将数据库内的表名,生成上面这种形式:
为什么不执行迁移操作?因为我们并没有向模型类执行:新增表、或者新增、修改字段等操作。
二、ORM外键关联
关联类型主要分为三类 跟MySQL类型一样一对多外键字段建在多的一方多对多外键字段建在第三张关系表一对一外键字段建在查询频率较高的表中ORM一对多外键字段建在多的一方publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)多对多外键字段可以直接写在某张表中 orm会自动帮你创建第三张表authors = models.ManyToManyField(to='Authors')一对一外键字段建在查询频率较高的表中detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)
'''Django1.x版本无需写级联删除级联更新,2.x需要,此处是以2.x展示'''class Book(models.Model):title = models.CharField(max_length=32)# 书与出版社是一对多 书是多publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE) ''' 级联删除 注意主键不需要自己去添加ID ORM会自动添加 '''# 书与作者是多对多authors = models.ManyToManyField(to='Authors')class Publish(models.Model):pub_name = models.CharField(max_length=32)class Authors(models.Model):name = models.CharField(max_length=32)detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)class AuthorDetail(models.Model):phone = models.BigIntegerField()
Django请求的生命周期流程图
django的生命周期是从用户发送HTTP请求数据到网站响应的过程。整个过程的流程包括:浏览器发送HTTE请求(通过orm) MySI获取数据->wsgiref服务>视图层一>中间件->templates模板层->路由层urls->视图层渲染->视图层views-> 中间件smodels模型层->响应内容给浏览器一>1.首先,用户在浏览器中输入一个url,发送一个GET方法的reguest请求。2.在django中有一个封装了socket的方法模块wsgiref,监听端口接受request请求,初步封装传送到中间件。3.由中间件传输到路由系统中进行路由分发,匹配对应的视图函数。4.将request请求传输到views视图函数中进行逻辑处理。5.调用models中表对象,通过orm操作数据库拿到数据,同时去templates中相应的模板进行渲染6.用response响应传输到中间件,依次处理,响应给浏览器展示给用户
Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。当然我们也可以称它为:WSGI协议
而wsgiref模块就是python基于WSGI协议开发的服务模块。其支持的并发量不高,但用于我们开发环境足够了,待程序的上线再使用其他的Web服务提高我们运行程序的服务器性能。
相关文章:

Django(三、数据的增删改查、Django生命周期流程图)
文章目录 一、 基于ORM进行的CURDuser_list:作为主页使用路由文件urls.py配置如下:add.html:用于新增用户的数据页add页面视图函数如下:edit.html:修改数据的页面那么来总结一下上序所操作所用到的内容。 导入已存在的表其方式有两…...

Linux 部署Sentinel控制台
Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 1.版本选择 SpringCloudAlibaba SpringClo…...
服务器如何下载百度网盘数据
百度网盘作为镜像 国外用户传数据到我们服务器比较慢,但是传输百度网盘速度还是可以的。 这样我们就可以将百度网盘作为一个文件中转站。 但Linux系统下使用百度网盘有些麻烦,虽然百度网盘也有Linux版本,但服务器没开启图形界面,使用的是命令行。这个时候就得感谢开发者Ho…...

POJ 3254 Corn Fields 状态压缩DP(铺砖问题)
一、题目大意 我们要在N * M的田地里种植玉米,有如下限制条件: 1、对已经种植了玉米的位置,它的四个相邻位置都无法继续种植玉米。 2、题目中有说一些块无论如何,都无法种植玉米。 求所有种植玉米的方案数(不种植也…...

transformers安装避坑
1.4 下载rust编辑器 看到这里你肯定会疑惑了,我们不是要用python的吗? 这个我也不知道,你下了就对了,不然后面的transformers无法安装 因为是windows到官网选择推荐的下载方式https://www.rust-lang.org/tools/install。 执行文…...

牛客、赛码网OJ调试(全)
现在无论开发还是测试,面试的时候都需要考察代码能力。 从测试的职业发展来看,现在市场上对于纯功能测试的需求很少,招聘方均要求面试者一方面具备测试基础能力,也要求有点代码能力。 对于测试来说,除了测试开发&#…...
【CSS】全局声明引入自定义字体
以下用vue项目为例,其他的也是类似! 在Vue.js中可以使用全局样式表来定义字体。通常,可以在项目中的主样式表中定义全局字体,然后确保该样式表在整个应用程序中被引入。 以下是一般的步骤: 在项目中创建一个全局样式…...
「Flask」路由+视图函数
路由 路由的作用是将 HTTP 请求的 URL 路径映射到相应的函数处理程序。这样我们在开发过程中,就能将不同的 URL 路径与相应的函数处理程序关联起来,从而实现对 Web 应用的灵活控制。 路由可以分为静态路由和动态路由。两者主要是在形式上有一些区别&am…...

信息系统项目管理师 教材目录、考试大纲、考情
文章目录 考情考试大纲第1章 信息化发展第2章 信息技术发展第3章 信息系统治理第4章 信息系统管理第5章 信息系统工程第6章 项目管理概论第7章 项目立项管理第8章 项目整合管理第9章 项目范围管理272第10章 项目进度管理297第11章 项目成本管理334第12章 项目质量管理358第13章…...
python线性回归实现
import random import torch# ①根据带有噪声的线性模型构造一个人造数据集。 使用线性模型参数w[2,−3.4] b4.2和噪声项ϵ生成数据集及其标签 def synthetic_data(w, b, num_examples):"""生成 y Xw b 噪声。"""# 生成均值为0,标…...

【JavaEESpring】认识Spring
认识Spring 1. 什么是框架2. SpringBoot 介绍2.1 Spring 的介绍2.2 SpringBoot 1. 什么是框架 框架(Framework) ,意思是框架、机制、准则。通俗的来讲: 框架是实现某种功能的半成品, 他提供了⼀些常⽤的⼯具类, 我们在框架的基础上, 可以更加⾼效的进⾏开发 后端框…...
Rust逆向学习 (5)
文章目录 Reverse for Vecvec! 与 添加元素元素访问元素遍历枚举数组弹出最后一个元素——pop 总结 本文将对Rust中的通用集合类型——动态数组 Vec进行学习,对应参考书中的第8章。 Reverse for Vec Vec是Rust中的动态数据结构,与C中的vector功能类似。…...
89.STL-函数对象的使用(仿函数)
目录 1.什么是函数对象 2.仿函数示例 3.代码示例 1.什么是函数对象 函数对象是C中的一种编程概念,也称为函数符或仿函数。其实就是重载“()”操作符,使得类对象可以像函数那样调用。 分类:假定某个类有一个重载的operator(),而且重载的oper…...

文件管理技巧:按文件容量大小分类,自动移动至目标文件夹的方法
按文件容量大小分类可以帮助快速识别和筛选出不同大小的文件。这样做有很多好处。首先,可以轻松地查找和访问特定大小的文件,提高工作效率。其次,通过将不同大小的文件分类,可以更好地了解和掌控文件的使用情况,避免存…...

[架构之路-246]:目标系统 - 设计方法 - 软件工程 - 需求工程- 需求开发:获取、分析、定义、验证
目录 前言: 架构师为什么需要了解需求分析 一、需求工程概述 1.1 概述 1.2 需求工程的两大部分 (1)需求开发:系统工程师的职责、目标系统开发角度 (2)需求管理:项目管理者的职责、项目管…...

轻量日志管理方案-[EFK]
使用FileBeat进行日志文件的数据收集,并发送到ES进行存储,最后Kibana进行查看展示; 这个应该是最简单,轻量的日志收集方案了。 最总方案为:FileBeatESKibana ; 【Kibana过于强大,感觉可以无限扩展】 文章目…...

Halcon WPF 开发学习笔记:HSmartWindowControlWPF正常加载
文章目录 加载问题相关文章彻底解决 加载问题 我们在WPF中使用Halcon的时候,会出现图片被拉伸的问题,需要拖动才可以解决,我网上找了好久,终于找到了如何成功解决这个问题。 相关文章 3.7 Halcon 窗体显示对象消失问题 【halcon】…...

mybatis的简单教程
整体就是mysql里存了一张表,然后在java程序里用mybatis把数据读出来的一个简单示例。 库 blog里有一张表 article 整个项目就是增加了这3个文件 首先是mybatis-config.xml文件 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE c…...

数据结构 队列(C语言实现)
目录 1.队列的概念及结构2.队列的代码实现 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通俗易懂,风趣幽默,忍不住分享一下给大家。 点击跳转到网站。 1.队列的概念及结构 队列:只允许在…...
Android---屏幕适配的处理技巧
在几年前,屏幕适配一直是困扰 Android 开发工程师的一大问题。但是随着近几年各种屏幕适配方案的诞生,以及谷歌各种适配控件的推出,屏幕适配也显得越来越容易。下面,我们就来总结一下关于屏幕适配的那些技巧。 ConstraintLayout …...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...