Django请求生命周期流程图与ORM表关系
Django请求生命周期流程图与ORM表关系
一、ORM表关系
-
关系型数据库的表与表之间往往存在一定的关系,由于Django的模型是数据库表与Python类之间的映射,因此Django提供了3种最常用的数据库表之间关系的支持:一对一、一对多、多对多
-
表之间的关系都是通过外键来进行关联的
1.三种对应关系
1.1 一对多
-
一对多关系:一张数据库表中的一条记录与另一张数据库表中的多条记录相对应
-
Django实现方式:通过
ForeignKey
来实现的
1.2 一对一
-
一张表的一条记录一定只能与另外一张表的一条记录进行对应。
-
Django实现方式:在Django中一对一是通过
models.OneToOneField
来实现的。这个OneToOneField
其实本质上就是一个外键,只不过这个外键有一个唯一约束(unique key)
,来实现一对一。
1.3 多对多
-
一对表中(A)的一条记录能够对应另外一张表(B)中的多条记录;同时B表中的一条记录也能对应A表中的多条记录
-
Django实现方式:Django为这种多对多的实现提供了专门的
Field
。叫做ManyToManyField
2.表关系判断
- 得出表关系结论需要双向进行观察对比(换位思考)
3.表关系举例
- 书籍表 : books
- 出版社表 : publish
- 作者表 : author
- 作者介绍表 : author_info
一本书可以对用多位作者, 一位作者可以对应多本书 (多对多)
一本书只能有一个出版社, 一个出版社可以出版多本书 (一对多)
一位作者对应一个作者简介,一个作者简介对应一位作者 (一对一)
4.ORM 针对外键字段的创建位置
-
一对一:建在任何一方都可以, 但是推荐建在查询频率较高的表中
-
一对多:推荐建在多的一方
-
多对多:
- 手动创建
- 在ORM中,建在任何一方都可以, 但是推荐建立在查询频率较高的表中
5.创建外键示例
- models.py 文件
# 书籍表
class Book(models.Model):
# 不创建主键,orm会自动帮你创建
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places) # 最大位数8位,小数点占两位
# 建立出版社外键, 默认就是 Publish 表的主键, 并且自动在外键字段后面加上"_id"后缀
publish = models.ForeignKey(to='Publish')
# 建立作者外键, 自动帮你创建book与author的中间表, 虚拟的字段并不会在表中实例化出来, 只是告诉ORM创建第三张关系表
authors = models.MaryToMaryField(to='Author')
# 出版社表
class Publish(models.Model):
title = models.CharField(max_length=32)
email = models.EmailField()
# 作者表
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
# 建立作者简介外键
author_info = models.OneToOneField(to='Author_info')
# 作者简介表
class Author_info(models.Model):
phone = models.BigIntegerField()
addr = models.CharField(max_length=128)
二、Django生命请求周期流程图
1.浏览器客户端发送请求
在浏览器输入url,譬如www.baidu.com,浏览器会自动补全协议(http),变为http://www.baidu.com,现在部分网站都实现了HSTS机制,服务器自动从http协议重定向到https协议,
2.DNS解析
通过域名去查找IP,先从本地缓存查找,其中本地的hosts文件也绑定了对应IP,若在本机中无法查到,那么就会去请求本地区域的域名服务器(通常是对应的网络运营商如电信),这个通过网络设置中的LDNS去查找,如果还是没有找到的话,那么就去根域名服务器查找,这里有所有因特网上可访问的域名和IP对应信息(根域名服务器全球共13台)
路由转发:通过网卡、路由器、交换机等设备,实现两个IP地址之间的通信。用到的主要就是路由转发技术,根据路由表去转发报文,还有子网掩码、IP广播等
3.建立连接
通过TCP协议的三次握手建立连接
4.传输报文
建立连接后,客户端会通过TCP依次、有序的发送一定大小的报文,其中包括了超时重传、阻塞窗口等等概念,用来保证数据包的完整、有序
http协议使用的明文传输,所有内容都是直接可读的
https协议是基于SSL/TLS加密,而SSL/TLS是基于TCP协议的,也就是http协议报文包装成TCP报文进行的加密,使用https协议的话,如果本地没有证书和公钥,那么会从服务器获取证书并且进行验证。
5.Nginx处理
当前django框架开发的web项目,主流使用的服务器架构是:nginx+uWSGI+django。
nginx监听公网IP的某个端口,譬如80,接收到请求后,分2种情况处理请求:
如果是静态资源(如javascript、css、图片等)的请求,那么nginx直接获取到该资源,返回给用户。
如果是动态内容的请求,那么nginx就将请求转发到uWSGI,使用的协议一般都是uwsgi,性能最好。
有些reqeust会分多个数据包进行发送,nginx会缓存等待整个request接收完成才调用uWSGI
如果使用的https,那么加密、解密都在nginx中进行处理
6.uWSGI处理
uWSGI监听本机IP的某个端口,譬如3308,接收到nginx转发来的请求后,通过将http协议转换为WSGI协议,和django程序之间进行通信。
7.WSGIHandler处理
当django接受到一个请求时,会初始化一个WSGIHandler,可以在项目下的wsgi.py文件进行跟踪查看。
8、中间件middleware的process_request处理
中间件的process_request方法列表对request对象进行处理
9、URLConf路由匹配
通过urls.py文件中的 urlpatterns 配置找到对应的
视图函数或者视图类的方法,如果没有找到匹配的方法,那么就会触发异常,由中间件的process_exception 进行处理
10、middleware的process_view
调用中间件的 process_view 方法进行预处理
11、views处理request
调用对应的视图函数或视图类的方法处理request,譬如获取GET和POST参数,并且调用特定的模型对象执行数据库操作,如果没有数据库操作,那么就直接跳到后续的14步了
12、models处理
视图方法中,一般情况下都需要调用模型类进行数据操作,一般是通过模型的manager管理类进行操作的,如:MyModel.objects.get(pk=1)
如果没有数据操作,那么这一步和下一步就忽略
13、数据库操作
如果django通过模型类执行对数据库的增删改查,那么此时整个流程就会在对应的数据库中执行
14、views处理数据
视图方法获取到数据后:
将数据封装到一个context字典当中,然后调用指定的template.html,通过模板中的变量、标签和过滤器等,再结合传入的数据context,会触发中间件的process_template_response方法,最终渲染成HttpResponse
不调用模板,直接返回数据,譬如 JsonResponse、FileResponse等
执行redirect,生成一个重定向的HttpResponse,触发中间件的process_response后,返回到客户端,结束该web请求的生命周期
15、middleware的process_response
调用中间件的 process_response
方法进行处理,最后一个中间件的process_response执行完成后,返回到WSGIHandler类中
至此,django编程的处理部分完毕
16、WSGIHandler处理
WSGIHandler类获取到response后
先处理response的响应行和响应头,然后调用 start_response 返回http协议的 响应行和响应头 到uWSGI,这个
start_response 只能调用一次
第一步处理完成后,如果是文件需要对response进行,否则就直接将response作为http协议的body部分返回给uWSGI
17、uWSGI处理
uWSGI接收到django程序的返回后,将所有内容包装成http协议的内容后,通过uwsgi协议返回给nginx服务器处理
18、nginx处理响应请求
nginx获取到uWSGI的返回后,将response通过TCP协议返回给客户端
19、客户端接收响应
客户端接收到服务器的响应后,做对应的操作,譬如:显示在浏览器中,或是javascript的处理等
至此,整个web请求的生命周期结束。
版权声明:
作者:淘小欣
链接:https://blog.taoxiaoxin.club/149.html
来源:淘小欣的博客
文章版权归作者所有,未经允许请勿转载。

共有 0 条评论