一、概要
Django(维基百科) Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的软件设计模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的。并于2005年7月在BSD许可证下发布。这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的。
Django的主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don't Repeat Yourself)。在Django中Python被普遍使用,甚至包括配置文件和数据模型。
Django 于 2008年6月17日正式成立基金会。
Django吸引人的特点
在Python各种web框架中,Django的文档最完善、市场占有率最高、招聘职位最多!
二、特点
- Django是走大而全的方向,它最出名的是其全自动化的管理后台:只需要使用起ORM,做简单的对象定义,它就能自动生成数据库结构、以及全功能的管理后台。
- Django内置的ORM跟框架内的其他模块耦合程度高。应用程序必须使用Django内置的ORM,否则就不能享受到框架内提供的种种基于其ORM的便利;理论上可以切换掉其ORM模块,但这就相当于要把装修完毕的房子拆除重新装修,倒不如一开始就去毛胚房做全新的装修。
- Django的卖点是超高的开发效率,其性能扩展有限;采用Django的项目,在流量达到一定规模后,都需要对其进行重构,才能满足性能的要求。
- Django适用的是中小型的网站,或者是作为大型网站快速实现产品雏形的工具。
- Django模板的设计哲学是彻底的将代码、样式分离; Django从根本上杜绝在模板中进行编码、处理数据的可能。
三 Django 、Flask、Tornado的对比
- Django是大而全的方向,开发效率高。它的MTV框架,自带的ORM,admin后台管理,自带的sqlite数据库和开发测试用的服务器 给开发者提高了超高的开发效率
- Flask是轻量级的框架,自由,灵活,可扩展性很强,核心基于Werkzeug WSGI工具和jinja2模板引擎
- Tornado走的是少而精的方向,性能优越。它最出名的是异步非阻塞的设计方式,Tornado的两大核心模块:
- iostraem:对非阻塞式的socket进行简单的封装,
- ioloop:对I/O多路复用的封装,它实现了一个单例
四、Django版本介绍
1、Django对Python版本的依赖关系
Django 版本 | Python 版本 |
---|---|
1.8 | 2.7, 3.2 (until the end of 2016), 3.3, 3.4, 3.5 |
1.9, 1.10 | 2.7, 3.4, 3.5 |
1.11 | 2.7, 3.4, 3.5, 3.6 |
2.0 | 3.4, 3.5, 3.6 |
2.1 | 3.5, 3.6, 3.7 |
2、Django版本支持路线图
三、什么是WSGI
1、WSGI
首先我们来写一段通过编写标准的WSGI程序
from wsgiref.simple_server import make_server def wsgi_app(environ, start_response): # 调用服务器程序提供的 start_response,填入两个参数 状态码 跟返回头部的信息 start_response('200 OK', [('Content-Type', 'text/html')]) db= pymysql.connect(host="localhost",user="root", password="root",db="test",port=3306) cur = db.cursor() sql = "select name,password from user where id=1" result = cur.fetchone() # 必须返回可迭代对象,并指定编码 text = r'<h1>' + result[0] + '</h1>' return [.encode('utf8')] if __name__ == '__main__': # 创建一个服务器,IP127.0.0.1,端口是8000,处理函数是application httpd = make_server('127.0.0.1', 8000, wsgi_app) # 监听HTTP请求: httpd.serve_forever()
通过上面的代码我们发现传统的WSG编程有一下几个不足
- 应用中有多处需要连接数据库会怎样呢? 每个独立的WSG脚本,不应该重复写数据库连接的代码。 比较实用的办法是写一个共享函数,可被多个代码调用。
- 一个开发人员 确实 需要去关注如何输出Content-Type以及完成所有操作后去关闭数据库么? 此类问题只会降低开发人员的工作效率,增加犯错误的几率。 那些初始化和释放 相关的工作应该交给一些通用的框架来完成。
- 如果这样的代码被重用到一个复合的环境中会发生什么? 每个页面都分别对应独立的数据库和密码吗?
- 如果一个Web设计师,完全没有Python开发经验,但是又需要重新设计页面的话,又将发生什么呢? 一个字符写错了,可能导致整个应用崩溃。 理想的情况是,页面显示的逻辑与从数据库中读取记录分隔开,这样 Web设计师的重新设计不会影响到之前的业务逻辑(可跳过直接看四MVC设计模式)
2、WSGI介绍
- 概要
WSGI (Python Web Server Gateway Interface, Python Web服务器网关接口)是一个Web服务器和Web应用程序之间的标准化接口,用于增进应用程序在不同的Web服务器和框架之间的可移植性。关于该标准的官方说明可以参考PEP333。 - WSGI规范如下:
服务器的请求处理程序中要调用符合WSGI规范的网关接口;
网关接口调用应用程序,并且要定义start_response(status, headers)函数,用于返回响应;
应用程序中实现一个函数或者一个可调用对象webapp(environ, start_response)。其中environ是环境设置的字典,由服务器和WSGI网关接口设置,start_response是由网关接口定义的函数。
3、uwsgi
- 说明
与WSGI一样是一种通信协议,是uWSGI服务器的独占协议,用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型的描述,与WSGI协议是两种东西,据说该协议是fcgi协议的10倍快。
4、uWSGI
- 说明
是一个web服务器,实现了WSGI协议、uwsgi协议、http协议等
5、Django框架分析WSGI
1、WSGI
- django WSGI application
class WSGIHandler(base.BaseHandler): initLock = Lock() request_class = WSGIRequest def __call__(self, environ, start_response): # 1.加载中间件 if self._request_middleware is None: ... # 2. 处理请求 request = self.request_class(environ) # 3. 处理响应 response = self.get_response(request) # 设置响应头部 response_headers = [(str(k), str(v)) for k, v in response.items()] for c in response.cookies.values(): response_headers.append((str('Set-Cookie'), str(c.output(header='')))) # 4. server提供的回调方法,将响应的header和status返回给server start_response(force_str(status), response_headers) if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'): response = environ['wsgi.file_wrapper'](response.file_to_stream) return response
- 说明
- 加载所有中间件,以及执行框架相关的操作,设置当前线程脚本前缀,发送请求开始信号;
- 处理请求,调用get_response()方法处理当前请求,该方法的的主要逻辑是通过urlconf找到对应的view和callback,按顺序执行各种middleware和callback。
- 调用由server传入的start_response()方法将响应header与status返回给server。返回响应正文
2、WSGI Server
- 作用
负责获取http请求,将请求传递给WSGI application,由application处理请求后返回response。以Django内建server为例看一下具体实现。通过runserver运行django 项目,在启动时都会调用下面的run方法,创建一个WSGIServer的实例,之后再调用其serve_forever()方法启动服务 - 源码
def run(addr, port, wsgi_handler, ipv6=False, threading=False): server_address = (addr, port) if threading: httpd_cls = type(str('WSGIServer'), (socketserver.ThreadingMixIn, WSGIServer), {}) else: httpd_cls = WSGIServer # 这里的wsgi_handler就是WSGIApplication httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6) if threading: httpd.daemon_threads = True httpd.set_app(wsgi_handler) httpd.serve_forever()
四、MVC设计模式
1、说明
MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)Web 应用程序的软件设计模式
框架模式是指针对于某一特定领域,可以适用于各种应用的模式,即为专用领域提供通用的或现成的基础结构,以获得最高级别的重用性
最高级别,那么比它更低级别的还有什么?
软件生产中有三种级别的重用:
内部重用,即在同一应用中能公共使用的抽象块;
代码重用,即将通用模块组合成库或工具集,以便在多个应用和领域都能使用;
应用框架的重用,即为专用领域提供通用的或现成的基础结构,以获得最高级别的重用性。
2、模型(Model)
- 说明
管理应用程序的状态(通常是数据库操作),并约束改变状态的行为(或者叫做“业务规则”)。 - 作用
是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作,
3、视图(View)
- 说明
显示数据(数据库记录) - 作用
是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的前端网页。生成页面展示的html内容。
4、控制器(Controller)
- 说明
处理输入输出 - 作用
是应用程序中处理用户交互的部分。接受外部用户的操作,根据操作访问模型获取数据,并调用“视图”显示这些数据。控制器是将“模型”和“视图”隔离,并成为二者之间的联系纽带
5、交互示例图
-
示例图
- 说明
- 用户首先在界面中进行人机交互,例如在浏览器地址栏输入地址
- 然后请求发送到控制器,控制器根据请求类型和请求的指令发送到相应的模型,
- 模型可以与数据库进行交互,进行增删改查操作
- 完成之后,根据业务的逻辑选择相应的视图进行显示,
- 此时用户获得此次交互的反馈信息,用户可以进行下一步交互,如此循环
6、MVC的特性
- 耦合性低:
利用MVC可以实现视图层和控制层分离,允许视图层与控制层的分离开发,允许更改视图层代码而不用重新编译模型和控制器代码;模型是自包含的,并且与控制器和视图相分离,所以很容易进行数据库的迁移 - 重用性高:
对于不同网站和应用,由于视图层、控制层和模型层的低耦合性,同一模块代码往往可以重复使用
决定了MVC在大型网站开发和多人协作时的代码的易集成和可维护,这也是当今MVC较为流行的原因。 - 能使网站程序结构更合理
当我们去开发网站的时候,最笨的方法,你可能把每个页面建成一个python文件。如果你的网站只有两三个页面,那你可以不用MVC,但我们做一般的网站的时候,动辄几十个页面,把所有页面放在一个文件中显然不是我们所能接受的,于是你需要一个合理的思想去将你的代码分类,按功能把他们分成不同的目录,且由程序智能的载入调用,这就是MVC要帮助你做的 - 有利于团队开发
在开发过程中,可以更好的分工,更好的协作。有利于开发出高质量的软件。良好的项 目架构设计,将减少编码工作量
五、Django框架MTV
1、说明
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,
Django 里更关注的是模型(Model)、模板(Template)和视图(Views), Django 也被称为 MTV 框架 。
2、模型(Model)
- 说明
即模型层,即数据存取层。 该层处理与数据相关的所有事务: 如存取、如何验证有效
3、模板(Template)
- 说明
即表现层。 该层处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。
4、视图(View)
- 说明
即控制层(业务逻辑层)。 该层包含存取模型及调取恰当模板的相关逻辑。 你可以把它看作模型与模板之间的桥梁。
5、交互示意图
-
示例图
- 说明
- 浏览器发送请求(基本上是字节类型的字符串)到web服务器。
- web服务器(比如,Nginx)把这个请求转交到一个WSGI(比如,uWSGI),或者直接地文件系统能够取出一个文件(比如,一个CSS文件)。
- 不像web服务器那样,WSGI服务器可以直接运行Python应用。请求生成一个被称为environ的Ptyhon字典,而且,可以选择传递过去几个中间件的层,最终,达到Django应用。
- URLconf中含有属于应用的urls.py选择一个视图处理基于请求的URL的那个请求,这个请求就已经变成了HttpRequest——一个Python字典对象。
- 被选择的那个视图通常要做下面所列出的一件或者更多件事情
- 通过模型与数据库对话。
- 使用模板渲染HTML或者任何格式化过的响应。
- 返回一个纯文本响应(不被显示的)。
- 抛出一个异常。
- HttpResponse对象离开Django后,被渲染为一个字符串。
- 在浏览器见到一个美化的,渲染后的web页面