转自http://selfboot.cn/2016/07/28/forum_design_framework/html
————————————————————————————————————————————————————————————————————————————————————————————————————————————————python
以前用 Django 作过一个小的站点,感受Django太过笨重,因而就准备换一个比较轻量级的 Web 框架来玩玩。Web.py 做者已经挂掉,项目很久没有更新,因此不许备用它。而 Flask 也是一个成熟的轻量级 Web 框架,在 github 上有众多的 Star 和 Fork,文档和扩展也很丰富,值得学习。git
学习一个框架最好的方式就是用框架作一个项目,在实战中理解掌握框架。这里我用 Flask 框架,使用 Mysql 数据库作了一个论坛系统。麻雀虽小,五脏俱全,论坛效果图以下:github
下面是论坛的基本功能:web
完整的用户模块(注册、登陆,更改、找回密码、信息修改、站内消息通知);sql
丰富的论坛模块(建立、回复话题,站内搜索,markdown支持,@user 提醒);数据库
强大的后台管理,支持屏蔽用户、话题、评论,支持各类条件搜索话题、评论;编程
本博客将会用一系列文章,记录论坛系统搭建的过程,但愿对刚入门Web开发的同窗有所帮助。flask
咱们常常据说 Django, Flask 这些 python 语言的Web 框架
,那么框架究竟是什么,Web框架和Web服务器(Nginx, Apache等)有什么区别?离开框架还能用 Python 搭建Web站点吗?要解决这些疑问,咱们有必要来理解下 Web 服务器的工做原理,以及 Web 框架的本质。后端
当咱们在浏览器输入URL后,浏览器会先请求DNS服务器,得到请求站点的 IP 地址。而后发送一个HTTP Request(请求)给拥有该 IP 的主机,接着就会接收到服务器给咱们的 HTTP Response(响应),浏览器通过渲染后,以一种较好的效果呈现给咱们。这个过程当中,正是Web服务器在幕后默默作贡献。
简单来讲,Web服务器是在运行在物理服务器上的一个程序,它永久地等待客户端(主要是浏览器,好比Chrome,Firefox等)发送请求。当收到请求以后,它会生成相应的响应并将其返回至客户端。Web服务器经过HTTP协议与客户端通讯,所以也被称为HTTP服务器。
Web服务器的工做原理并不复杂,通常可分红以下4个步骤:创建链接、请求过程、应答过程以及关闭链接
。
创建链接:客户机经过TCP/IP协议创建到服务器的TCP链接。
请求过程:客户端向服务器发送HTTP协议请求包,请求服务器里的资源文档。
应答过程:服务器向客户机发送HTTP协议应答包,若是请求的资源包含有动态语言的内容,那么服务器会调用动态语言的解释引擎负责处理“动态内容”,并将处理获得的数据返回给客户端。由客户端解释HTML文档,在客户端屏幕上渲染图形结果。
关闭链接:客户机与服务器断开。
下面咱们实现一个简单的 Web 服务器。运行示例程序后,会监听本地端口 8000,在浏览器访问 http://localhost:8000 就能看到响应内容。而咱们的程序也可以打印出客户端发来的请求内容,以下图:
这里Request 和 Response 都须要遵照 HTTP 协议,关于 HTTP 协议的详细内容,能够读读《HTTP 权威指南》,或者看我整理的HTTP 部份内容。
虽说web服务器的主要工做是根据request返回response,可是实际中的 Web 服务器远远比上面示例的复杂的多,由于要考虑的因素实在是太多了,好比:
缓存机制:讲一些常常被访问的页面缓存起来,提升响应速度;
安全:防止黑客的各类攻击,好比 SYN Flood 攻击;
并发处理:如何响应不一样客户端同时发起的请求;
日志:记录访问日至,方便作一些分析。
目前在UNIX和LINUX平台下使用最普遍的免费 Web 服务器有Apache和 Nginx 。
Web 服务器接受 Http Request,返回 Response,不少时候 Response 并非静态文件,所以须要有一个应用程序根据 Request 生成相应的 Response。这里的应用程序主要用来处理相关业务逻辑,读取或者更新数据库,根据不一样 Request 返回相应的 Response。注意这里并非 Web 服务器自己来作这件事,它只负责 Http 协议层面和一些诸如并发处理,安全,日志等相关的事情。
应用程序能够用各类语言编写(Java, PHP, Python, Ruby等),这个应用程序会从Web服务器接收客户端的请求,处理完成后,再返回响应给Web服务器,最后由Web服务器返回给客户端。整个架构以下:
以 Python 为例,使用Python开发Web,最原始和直接的办法是使用CGI标准,在1998年这种方式很流行。首先确保 Web 服务器支持CGI及已经配置了CGI的处理程序,而后设置好CGI目录,在目录里面添加相应的 python 文件,每个 python 文件处理相应输入,生成一个 html 文件便可,以下例:
#!/usr/bin/python # -*- coding: UTF-8 -*- print "Content-type:text/html" print # 空行,告诉服务器结束头部 print '<html>' print '<head>' print '<meta charset="utf-8">' print '</head>' print '<body>' print '<h2>Hello Word! 我是一个CGI程序</h2>' print '</body>' print '</html>'
这样在浏览器访问该文件就能够获得一个简单的 Hello World 网页内容。直接经过 CGI 写 Web 应用程序看起来很简单,每个文件处理输入,生成html。可是实际开发中,可能会遇到许多不方便的地方。好比:
每一个独立的CGI脚本可能会重复写数据库链接,关闭的代码;
后端开发者会看到一堆 Content-Type 等和本身无关的 html 页面元素;
早期开发站点确作了许多重复性劳动,后来为了减小重复,避免写出庞杂,混乱的代码,人们将 Web 开发的关键性过程提取出来,开发出了各类 Web 框架。有了框架,就能够专一于编写清晰、易维护的代码,无需关心数据库链接之类的重复性工做。
其中一种比较经典的Web框架采用了 MVC 架构,以下图所示:
用户输入 URL,客户端发送请求,控制器(Controller)
首先会拿到请求,而后用模型(Models)
从数据库取出全部须要的数据,进行必要的处理,将处理后的结果发送给 视图(View)
,视图利用获取到的数据,进行渲染生成 Html Response返回给客户端。
以 python web 框架 flask 为例,框架自己并不限定咱们用哪一种架构来组织咱们的应用,不过 flask 能够很好地支持以 MVC 方式组织应用。
控制器:flask 能够用装饰器来添加路由项,以下:
@app.route('/') def main_page(): pass
模型:主要用来取出须要的数据,以下面函数中操做:
@app.route('/') def main_page(): """Searches the database for entries, then displays them.""" db = get_db() cur = db.execute('select * from entries order by id desc') entries = cur.fetchall() return render_template('index.html', entries=entries)
视图:flask 利用 jinja2 来渲染页面,下面的模版文件指定了页面的样式:
{% for entry in entries %} <li> <h2>{{ entry.title }}</h2> <div>{{ entry.text|safe }}</div> </li> {% else %} <li><em>No entries yet. Add some!</em></li> {% endfor %}
咱们知道Python有着许多的 Web 框架,而同时又有着许多的 Web 服务器(Apache, Nginx, Gunicorn等),框架和Web服务器之间须要进行通讯,若是在设计时它们之间不能够相互匹配的,那么选择了一个框架就会限制对 Web 服务器的选择,这显然是不合理的。
那么,怎样确保能够在不修改Web服务器代码或网络框架代码的前提下,使用本身选择的服务器,而且匹配多个不一样的网络框架呢?答案是接口,设计一套双方都遵照的接口就能够了。对python来讲,就是WSGI
(Web Server Gateway Interface,Web服务器网关接口)。其余编程语言也拥有相似的接口:例如Java的Servlet API和Ruby的Rack。
Python WSGI的出现,让开发者能够将 Web 框架与 Web 服务器的选择分隔开来,再也不相互限制。如今,你能够真正地将不一样的 Web 服务器与Web框架进行混合搭配,选择知足本身需求的组合。例如,可使用 Gunicorn 或Nginx/uWSGI来运行Django、Flask或web.py应用。