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

文章目录

一、 基于ORM进行的CURD

本质上就是通过面向对象的方式,对数据库的数据进行增、删、改、查。

这里将会将我们之前所有内容结合到一起,首先确保基于上序操作已经建立好了UserInfo表,那么我们还需要建立几个HTML文件,只需要关注与提交数据有关的标签

user_list:作为主页使用

python 复制代码
<!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:用于新增用户的数据页

python 复制代码
<!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页面视图函数如下:

python 复制代码
	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:修改数据的页面

python 复制代码
<!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编号,那么我们需要接收这个编号,再根据它来修改用户信息。

python 复制代码
	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内携带用户的编号,那么基本操作套路就是一样了。

python 复制代码
	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/')  # 重定向到主页,达到一个刷新的效果

已经达到了我们预期的效果,点击一下删除按钮整行数据。

那么来总结一下上序所操作所用到的内容。
python 复制代码
	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里面的类,而我们目前只了解怎么通过它创建数据库表,而没有了解过如何使用它导入已经存在数据库内的表。

其方式有两种

在模型内,按照表的完整数据结构创建类名、类属性,整体代码如下:

python 复制代码
	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外键关联

python 复制代码
		关联类型主要分为三类 跟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)
python 复制代码
		'''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请求的生命周期流程图

python 复制代码
	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服务提高我们运行程序的服务器性能。

相关推荐
tatasix34 分钟前
MySQL UPDATE语句执行链路解析
数据库·mysql
南城花随雪。1 小时前
硬盘(HDD)与固态硬盘(SSD)详细解读
数据库
儿时可乖了1 小时前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
懒是一种态度1 小时前
Golang 调用 mongodb 的函数
数据库·mongodb·golang
天海华兮1 小时前
mysql 去重 补全 取出重复 变量 函数 和存储过程
数据库·mysql
gma9992 小时前
Etcd 框架
数据库·etcd
爱吃青椒不爱吃西红柿‍️2 小时前
华为ASP与CSP是什么?
服务器·前端·数据库
陈王卜2 小时前
django+boostrap实现发布博客权限控制
java·前端·django
Yz98762 小时前
hive的存储格式
大数据·数据库·数据仓库·hive·hadoop·数据库开发
苏-言3 小时前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring