Django 基于ORM的CURD、外键关联,请求的生命周期

文章目录

  • 基于ORM进行的CURD
  • 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>&nbsp;&nbsp;<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服务提高我们运行程序的服务器性能。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023最新版本 从零基础入门C++与QT(学习笔记) -5- 动态内存分配(new)

&#x1f38f;C的动态内存要比C方便 &#x1f384;注意C申请内存的时候可以直接的初始化&#xff01;&#xff01;&#xff01; &#x1f384;格式&#xff08;申请一块内存&#xff09; &#x1f388;new(关键字) 变量类型 &#x1f384;格式&#xff08;申请多块内存&am…

Docker - 网络

Docker - 网络 理解Docker0 # 我们发现这个容器带来网卡&#xff0c;都是一对对的 # evth-pair 就是一对的虚拟设备接口&#xff0c;他们都是成对出现的&#xff0c;一段连着协议&#xff0c;一段彼此相连 # 正因为有了这个特性&#xff0c;evth-pair 充当一个桥梁&#xff0…

时分复用(Time Division Multiplexing, TDM)介绍(同步时分复用、异步时分复用(统计时分复用))

文章目录 时分复用技术: 原理与应用概述1. 时分复用的基本原理1.1 定义和工作方式1.2 同步与异步时分复用 2. 时分复用的技术特点2.1 优点2.2 缺点 3. 时分复用的应用3.1 电信网络3.2 数字视频广播3.3 光纤通信 4. 时分复用模拟代码参考文献总结 时分复用技术: 原理与应用 概述…

VMware 安装CentOS7

一、软件准备 VMware 虚拟机安装 官网下载链接&#xff1a;VMware pro 17 下载链接 下载 VMware Workstation Pro | CN vm安装教学就不在细说&#xff0c;纯傻瓜式安装 Centos 7镜像文件下载 下载地址&#xff1a; Index of /centos/ | 清华大学开源软件镜像站 | Tsinghua O…

【Effect C++ 笔记】(四)设计与声明

【四】设计与声明 条款18 &#xff1a; 让接口容易被正确使用&#xff0c;不易被误用 Item 18: 让接口容易被正确使用&#xff0c;不易被误用 Make interfaces easy to use correctly and hard to use incorrectly. “让接口容易被正确使用&#xff0c;不易被误用”&#xff0…

(十一)Flask模板引擎jinja2

模板引擎Jinja2 一、简介及基本使用&#xff1a; Flask使用Jinja2作为默认的模板引擎。Jinja2是一个功能强大且易于使用的模板引擎&#xff0c;它允许我们在HTML中嵌入Python代码&#xff0c;并通过将模板和数据进行渲染来生成动态内容。 实战之在Flask中使用Jinja2模板引擎…

colormap与colorbar应用

一&#xff0c;colormap 常见色度枚举值如下 应用如下 img cv2.applyColorMap(img, cv2.COLORMAP_JET) cv2.imshow(img,img) cv2.waitKey(0) cv2.destroyAllWindows() 常用的COLORMAP_JET效果如下&#xff0c;该模式常用于生成热力图 二&#xff0c;colorbar colorbar所有…

python画出2行4列个子图

代码 import matplotlib.pyplot as plt# 数据 areas [50, 80, 120] shenzhen_prices [1500, 2000, 2500] guangzhou_prices [1200, 1800, 2300] zhengzhou_prices [800, 1200, 1500]# 创建一个包含2行4列共8个子图的图表 fig, axs plt.subplots(2, 4, figsize(14, 8))def…

一文搞懂Transformer

近期Transformer系列模型的出现&#xff0c;增加了CV领域的多样性。但是Transformer这一不同领域的模型对学习者来说需要一个细致的学习过程.下面就是本菜鸟总结学习路线。 Transformer是基于attention机制。而attention机制又在Encoder、Decode中。本篇博客将从Attention->…

sqli-labs(Less-3)

1. 通过构造id1’ 和id1’) 和id1’)–确定存在注入 可知原始url为 id(‘1’) 2.使用order by 语句猜字段数 http://127.0.0.1/sqlilabs/Less-3/?id1) order by 4 -- http://127.0.0.1/sqlilabs/Less-3/?id1) order by 3 --3. 使用联合查询union select http://127.0.0.1…

Sentinel 流控规则

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 SpringbootDubboNacos 集成 Sentinel&…

探索未来,开启无限可能:打造智慧应用,亚马逊云科技大语言模型助您一臂之力

文章目录 什么是大模型&#xff1f;大模型训练方法亚马逊云科技推出生成式AI新工具 —— aws toolkit使用教程 总结 什么是大模型&#xff1f; 近期&#xff0c;生成式大模型是人工智能领域的研究热点。这些生成式大模型&#xff0c;诸如文心一言、文心一格、ChatGPT、Stable …