当前位置: 首页 > news >正文

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>&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服务提高我们运行程序的服务器性能。

相关文章:

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

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

Linux 部署Sentinel控制台

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

服务器如何下载百度网盘数据

百度网盘作为镜像 国外用户传数据到我们服务器比较慢,但是传输百度网盘速度还是可以的。 这样我们就可以将百度网盘作为一个文件中转站。 但Linux系统下使用百度网盘有些麻烦,虽然百度网盘也有Linux版本,但服务器没开启图形界面,使用的是命令行。这个时候就得感谢开发者Ho…...

POJ 3254 Corn Fields 状态压缩DP(铺砖问题)

一、题目大意 我们要在N * M的田地里种植玉米&#xff0c;有如下限制条件&#xff1a; 1、对已经种植了玉米的位置&#xff0c;它的四个相邻位置都无法继续种植玉米。 2、题目中有说一些块无论如何&#xff0c;都无法种植玉米。 求所有种植玉米的方案数&#xff08;不种植也…...

transformers安装避坑

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

牛客、赛码网OJ调试(全)

现在无论开发还是测试&#xff0c;面试的时候都需要考察代码能力。 从测试的职业发展来看&#xff0c;现在市场上对于纯功能测试的需求很少&#xff0c;招聘方均要求面试者一方面具备测试基础能力&#xff0c;也要求有点代码能力。 对于测试来说&#xff0c;除了测试开发&#…...

【CSS】全局声明引入自定义字体

以下用vue项目为例&#xff0c;其他的也是类似&#xff01; 在Vue.js中可以使用全局样式表来定义字体。通常&#xff0c;可以在项目中的主样式表中定义全局字体&#xff0c;然后确保该样式表在整个应用程序中被引入。 以下是一般的步骤&#xff1a; 在项目中创建一个全局样式…...

「Flask」路由+视图函数

路由 路由的作用是将 HTTP 请求的 URL 路径映射到相应的函数处理程序。这样我们在开发过程中&#xff0c;就能将不同的 URL 路径与相应的函数处理程序关联起来&#xff0c;从而实现对 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&#xff0c;标…...

【JavaEESpring】认识Spring

认识Spring 1. 什么是框架2. SpringBoot 介绍2.1 Spring 的介绍2.2 SpringBoot 1. 什么是框架 框架(Framework) &#xff0c;意思是框架、机制、准则。通俗的来讲: 框架是实现某种功能的半成品, 他提供了⼀些常⽤的⼯具类, 我们在框架的基础上, 可以更加⾼效的进⾏开发 后端框…...

Rust逆向学习 (5)

文章目录 Reverse for Vecvec! 与 添加元素元素访问元素遍历枚举数组弹出最后一个元素——pop 总结 本文将对Rust中的通用集合类型——动态数组 Vec进行学习&#xff0c;对应参考书中的第8章。 Reverse for Vec Vec是Rust中的动态数据结构&#xff0c;与C中的vector功能类似。…...

89.STL-函数对象的使用(仿函数)

目录 1.什么是函数对象 2.仿函数示例 3.代码示例 1.什么是函数对象 函数对象是C中的一种编程概念&#xff0c;也称为函数符或仿函数。其实就是重载“()”操作符&#xff0c;使得类对象可以像函数那样调用。 分类:假定某个类有一个重载的operator()&#xff0c;而且重载的oper…...

文件管理技巧:按文件容量大小分类,自动移动至目标文件夹的方法

按文件容量大小分类可以帮助快速识别和筛选出不同大小的文件。这样做有很多好处。首先&#xff0c;可以轻松地查找和访问特定大小的文件&#xff0c;提高工作效率。其次&#xff0c;通过将不同大小的文件分类&#xff0c;可以更好地了解和掌控文件的使用情况&#xff0c;避免存…...

[架构之路-246]:目标系统 - 设计方法 - 软件工程 - 需求工程- 需求开发:获取、分析、定义、验证

目录 前言&#xff1a; 架构师为什么需要了解需求分析 一、需求工程概述 1.1 概述 1.2 需求工程的两大部分 &#xff08;1&#xff09;需求开发&#xff1a;系统工程师的职责、目标系统开发角度 &#xff08;2&#xff09;需求管理&#xff1a;项目管理者的职责、项目管…...

轻量日志管理方案-[EFK]

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

Halcon WPF 开发学习笔记:HSmartWindowControlWPF正常加载

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

mybatis的简单教程

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

数据结构 队列(C语言实现)

目录 1.队列的概念及结构2.队列的代码实现 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站。 1.队列的概念及结构 队列&#xff1a;只允许在…...

Android---屏幕适配的处理技巧

在几年前&#xff0c;屏幕适配一直是困扰 Android 开发工程师的一大问题。但是随着近几年各种屏幕适配方案的诞生&#xff0c;以及谷歌各种适配控件的推出&#xff0c;屏幕适配也显得越来越容易。下面&#xff0c;我们就来总结一下关于屏幕适配的那些技巧。 ConstraintLayout …...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...