Django(三、数据的增删改查、Django生命周期流程图)

news2024/11/16 19:58:20

文章目录

  • 一、 基于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>&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) # male
		
        return 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.coloradmin.cn/o/1200922.html

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

相关文章

深度学习笔记--基于C++手撕self attention机制

目录 1--self attention原理 2--C代码 3--拓展 3-1--mask self attention 3-2--cross attention 1--self attention原理 直观来讲&#xff0c;就是每个 token 的 Query 去和其它 token&#xff08;包括自身&#xff09;的 Key 进行 dot product&#xff08;点积&#xff0…

Tektronix(泰克)示波器TBS1102B测试电压

对于 Tektronix TBS1102B 示波器来说&#xff0c;测试电压的步骤基本如下&#xff1a; 连接测量点&#xff1a; 将被测电路的测量点连接到示波器的输入通道。使用正确的探头并确保连接的极性正确。 选择通道&#xff1a; 选择示波器上的通道&#xff0c;你想要测量的电压可能连…

Python BeautifulSoup 库使用教程

文章目录 简介安装 BeautifulSoup 库BeautifulSoup 库的导入BeautifulSoup 库依赖的解析库创建 BeautifulSoup 对象CSS选择器1、通过标签名查找2、通过 CSS 的类名查找3、通过 Tag(标签) 的 id 查找4、通过 是否存在某个属性来查找5、通过 某个标签是否存在某个属性来查找 获取…

【python后端】- 初识Django框架

Django入门 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f31d;分享学习心得&#xff0c;欢迎指正&#xff0c;大家一起学习成长&#xff01; 文章目录 Django入门…

Vue3:自定义图标选择器(包含 SVG 图标封装)

文章目录 一、准备工作&#xff08;在 Vue3 中使用 SVG&#xff09;二、封装 SVG三、封装图标选择器四、Demo 效果预览&#xff1a; 一、准备工作&#xff08;在 Vue3 中使用 SVG&#xff09; 本文参考&#xff1a;https://blog.csdn.net/houtengyang/article/details/1290431…

Carla之语义分割及BoundingBox验证模型

参考&#xff1a; Carla系列——4.Cara模拟器添加语义分割相机&#xff08;Semantic segmentation camera&#xff09; Carla自动驾驶仿真五&#xff1a;opencv绘制运动车辆的boudingbox&#xff08;代码详解&#xff09; Carla官网Bounding Boxes Carla官网创建自定义语义标签…

数据结构-堆和二叉树

目录 1.树的概念及结构 1.1 树的相关概念 1.2 树的概念 1.3 树的表示 1.4 树在实际中的应用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树的概念及结构 2.1 概念 2.2 特殊的二叉树 2.3 二叉树的存储 3.堆的概念及结构 4.堆的实现 初始化堆 堆的插入…

从0开始python学习-32.pytest.mark()

目录 1. 用户自定义标记 1.1 注册标记​编辑 1.2 给测试用例打标记​编辑 1.3 运行标记的测试用例 1.4 运行多个标记的测试用例 1.5 运行指定标记以外的所有测试用例 2. 内置标签 2.1 skip &#xff1a;无条件跳过&#xff08;可使用在方法&#xff0c;类&#xff0c;模…

6可靠的局域网组建

前面聊的拓扑结构都比较简单&#xff0c;所以能用&#xff0c;但是未必可靠。为了可靠&#xff0c;我们需要做冗余&#xff0c;同时需要做一些其他的配置。 生成树协议STP 假设交换机按照上面的方案连&#xff0c;虽然可以提高网络可靠性&#xff0c;但是因为形成了环路&#…

基于粒子群算法优化概率神经网络PNN的分类预测 - 附代码

基于粒子群算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于粒子群算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于粒子群优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络…

layui 表格(table)合计 取整数

第一步 开启合计行 是否开启合计行区域 table.render({elem: #myTable, url: ../baidui/, page: true, cellMinWidth: 100,totalRow:true,cols: [[ //表头//{ type: checkbox },{ type: checkbox,totalRowText: "合计" },//合计行区域{ field: id, align: center,…

c语言:解决数组中数组缺少单个的元素的问题

题目&#xff1a;数组nums包含从0到n的所以整数&#xff0c;但其中缺了一个。请编写代码找出那个缺失的整数。O(n)时间内完成。 如&#xff0c;输入&#xff1a;【3&#xff0c;0&#xff0c;1】。 输出&#xff1a; 2 三种方法 &#xff1a; 方法1&#xff1a;排序&#xf…

递归和master公式 系统栈 + 计算时间复杂度

前置知识&#xff1a;无 1&#xff09;从思想上理解递归&#xff1a;对于新手来说&#xff0c;递归去画调用图是非常重要的&#xff0c;有利于分析递归 2&#xff09;从实际上理解递归&#xff1a;递归不是玄学&#xff0c;底层是利用系统栈来实现的 3&#xff09;任何递归函…

Autosar UDS开发01(UDS诊断入门概念(UDSOnCan))

目录 回顾接触UDS的过程 UDS基本概念 UDS的作用 UDS的宏观认识 UDS的CAN通讯链路 UDS的报文种类 回顾接触UDS的过程 自21年毕业后&#xff0c;我一直干了2年的Autosar CAN通讯开发。 开发的主要内容简单概括就是&#xff1a;应用报文开发、网管报文开发、休眠唤醒开发&am…

职业迷茫,我该如何做好职业规划

案例25岁男&#xff0c;入职2月&#xff0c;感觉自己在混日子&#xff0c;怕能力没有提升&#xff0c;怕以后薪资也提不起来。完全不知道应该往哪个方向进修&#xff0c;感觉也没有自己特别喜欢的。感觉自己特别容易多想&#xff0c;想多年的以后一事无成的样子。 我觉得这个案…

腾讯云5年服务器CVM和3年轻量应用服务器配置价格表

腾讯云3年轻量和5年云服务器CVM活动入口&#xff0c;3年轻量应用服务器配置可选2核2G4M和2核4G5M带宽&#xff0c;5年CVM云服务器可以选择2核4G和4核8G配置可选&#xff0c;阿腾云atengyun.com分享腾讯云3年轻量应用服务器和5年云服务器CVM活动入口和配置报价&#xff1a; 目录…

3.如何实现 API 全局异常处理?-web组件篇

文章目录 1. 统一异常处理 1. 统一异常处理 在 Spring MVC 中&#xff0c;通过 ControllerAdvice ExceptionHandler 注解&#xff0c;声明将指定类型的异常&#xff0c;转换成对应的 CommonResult 响应。实现的代码&#xff0c;可见 GlobalExceptionHandler类。

【微软技术栈】C#.NET 如何使用本地化的异常消息创建用户定义的异常

本文内容 创建自定义异常创建本地化异常消息 在本文中&#xff0c;你将了解如何通过使用附属程序集的本地化异常消息创建从 Exception 基类继承的用户定义异常。 一、创建自定义异常 .NET 包含许多你可以使用的不同异常。 但是&#xff0c;在某些情况下&#xff0c;如果它们…

springboot苍穹外卖实战:七、店铺营业状态设置与查询+接口文档多端分组优化

店铺营业状态设置与查询 注意&#xff0c;先把测试类最上面的SpringBootTest注解注释掉&#xff0c;否则每次启动项目都会自动帮你测试一遍&#xff0c;导致项目启动变慢。 其次&#xff0c;该项目没有设置相应拦截器对付以下情况&#xff1a;用户使用过程中商家突然暂停营业&…

Django(复习篇)

项目创建 1. 虚拟环境 python -m venv my_env ​ cd my_env activate/deactivate ​ pip install django ​2. 项目和app创建 cd mypros django-admin startproject Pro1 django-admin startapp app1 ​3. settings配置INSTALLED_APPS【app1"】TEMPLATES【 DIRS: [os.pat…