Django设计模式 Django之MVC(MTV)设计模式 四、Django RestframWork中的REST设计

一、传统MVC

首先说说Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,

模型负责业务对象与数据库的映射(ORM),

视图负责与用户的交互(页面),

控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:
Django设计模式
Django之MVC(MTV)设计模式
四、Django RestframWork中的REST设计

二、Django的MTV (本质和MVC一样)

Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:

M 代表模型(Model):负责业务对象和数据库的关系映射(ORM)。

T 代表模板 (Template):负责如何把页面展示给用户(html)。

V 代表视图(View):负责业务逻辑,并在适当时候调用Model和Template。

除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:

Django设计模式
Django之MVC(MTV)设计模式
四、Django RestframWork中的REST设计

1,Web服务器(中间件)收到一个http请求

2,Django在URLconf里查找对应的视图(View)函数来处理http请求

3,视图函数调用相应的数据模型来存取数据、调用相应的模板向用户展示页面

4,视图函数处理结束后返回一个http的响应给Web服务器

5,Web服务器将响应发送给客户端
这种设计模式关键的优势在于各种组件都是松耦合的。这样,每个由 Django驱动的Web应用都有着明确的目的,并且可独立更改而不影响到其它的部分。

比如,开发者更改一个应用程序中的 URL 而不用影响到这个程序底层的实现。设计师可以改变 HTML页面的样式而不用接触Python代码。

数据库管理员可以重新命名数据表并且只需更改模型,无需从一大堆文件中进行查找和替换。

落到实处,Django的MTV模式相对应的python文件如下

Django设计模式
Django之MVC(MTV)设计模式
四、Django RestframWork中的REST设计

Django设计模式
Django之MVC(MTV)设计模式
四、Django RestframWork中的REST设计

 Django设计模式
Django之MVC(MTV)设计模式
四、Django RestframWork中的REST设计

 三、Django是如何工作的?

Django设计模式
Django之MVC(MTV)设计模式
四、Django RestframWork中的REST设计

前面的图片展示了从一个访客的浏览器到Django应用并返回的一个web请求的简单历程。如下是数字标识的路径:

浏览器发送请求(基本上是字节类型的字符串)到web服务器。
web服务器(比如,Nginx)把这个请求转交到一个WSGI(比如,uWSGI),或者直接地文件系统能够取出一个文件(比如,一个CSS文件)。
不像web服务器那样,WSGI服务器可以直接运行Python应用。请求生成一个被称为environ的Ptyhon字典,而且,可以选择传递过去几个中间件的层,最终,达到Django应用。
URLconf中含有属于应用的urls.py选择一个视图处理基于请求的URL的那个请求,这个请求就已经变成了HttpRequest——一个Python字典对象。
被选择的那个视图通常要做下面所列出的一件或者更多件事情:
通过模型与数据库对话。
使用模板渲染HTML或者任何格式化过的响应。
返回一个纯文本响应(不被显示的)。
抛出一个异常。
HttpResponse对象离开Django后,被渲染为一个字符串。
在浏览器见到一个美化的,渲染后的web页面。

四、Django RestframWork中的REST设计

REST,以及RESTful的讲解

REST简介

REST无状态的理解  

对于REST中无状态(stateless)的一点认识

--------------------------------------------------------

核心问题在于RESTful API设计,容易思考,但是不适合实际使用。

这个,就和设计网络协议一样,七层网络模型,理解很给力,实际还是采用四层网络模型一样。

---------------------------------------------------------

URI包括URL和URN两个类别,URL是URI的子集,所以URL一定是URI,而URI不一定是URL

URI = Universal Resource Identifier 统一资源标志符,用来标识抽象或物理资源的一个紧凑字符串。
URL = Universal Resource Locator 统一资源定位符,一种定位资源的主要访问机制的字符串,一个标准的URL必须包括:protocol、host、port、path、parameter、anchor。
URN = Universal Resource Name 统一资源名称,通过特定命名空间中的唯一名称或ID来标识资源。

REST的名称"表现层状态转化"(表现层"其实指的是"资源"(Resources)的"表现层"; URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的".html"后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴; 

互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。

就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源)

REST 是面向资源的,这个概念非常重要,而资源是通过 URI 进行暴露。

REST很好地利用了HTTP本身就有的一些特征,如HTTP动词、HTTP状态码、HTTP报头等等

任何一种架构风格的出现都有其期望的,对现有方案的改进或期望克服的问题。作为REST来说,它所期望的是组件的可伸缩性,组件的独立部署,接口统一等特性,而无状态作为实现这组需求的一个特性,个人认为是有必要清楚了解并实际开发过程中落实的。

是RESTful架构对于state的两个不同的解释: 应用状态(Application State)和资源状态(Resource State)。应用状态指的是与某一特定请求相关的状态信息,而资源状态则反映了某一存储在服务器端资源在某一时刻的特定状态,该状态不会因为用户请求而改变,任何用户在同一时刻对该资源的请求都会获得这一状态的表现(Representation)。RESTful架构要求服务器端不保有任何与特定HTTP请求相关的资源,所以应用状态必须由请求方在请求过程中提供。所以传递Session ID被认为是unRESTful的做法。反过来,user credential作为一种应用状态,是被期望由请求方提供的,所以在请求中传递user credentials(姑且忽略安全性问题)是符合RESTful架构规范的

可是http的创始人一直都觉得,在过去10几年来,所有的人都在错误的使用Http.

七宗罪的第一条,混乱。贪婪。无序。

这种做法让Roy Fielding很暴燥,他觉得这个世界不该这样的,所有的人都在误解而且在严重错误的误解Http的设计初衷,好比是发明了火药却只用它来做烟花爆竹。 第一个规则就是明确Url是什么,该怎么用。就是所有的Url本质来讲,都应该是一种资源。一个独立的Url地址,就是对应一个独一无二的资源。

对比传统API和

https://localhost:8080/myweb/getDogs --> GET /rest/api/dogs 获取所有小狗狗
https://localhost:8080/myweb/addDogs --> POST /rest/api/dogs 添加一个小狗狗
https://localhost:8080/myweb/updateDogs/:dog_id --> PUT /rest/api/dogs/:dog_id 修改一个小狗狗
https://localhost:8080/myweb/deleteDogs/:dog_id --> DELETE /rest/api/dogs/:dog_id 删除一个小狗狗
 

REST 系统的特征

客户-服务器(Client-Server): 提供服务的服务器和使用服务的客户需要被隔离对待。
无状态(Stateless): 来自客户的每一个请求必须包含服务器处理该请求所需的所有信息。换句话说,服务器端不能存储来自某个客户的某个请求中的信息,并在该客户的其他请求中使用。
可缓存(Cachable): 服务器必须让客户知道请求是否可以被缓存。(Ross:更详细解释请参考 理解本真的REST架构风格 以及 StackOverflow 的这个问题 中对缓存的解释。)
分层系统(Layered System): 服务器和客户之间的通信必须被这样标准化:允许服务器和客户之间的中间层(Ross:代理,网关等)可以代替服务器对客户的请求进行回应,而且这些对客户来说不需要特别支持。
统一接口(Uniform Interface): 客户和服务器之间通信的方法必须是统一化的。(Ross:GET,POST,PUT.DELETE, etc)
支持按需代码(Code-On-Demand,可选): 服务器可以提供一些代码或者脚本(Ross:Javascrpt,flash,etc)并在客户的运行环境中执行。这条准则是这些准则中唯一不必必须满足的一条。(Ross:比如客户可以在客户端下载脚本生成密码访问服务器。)