开发平台: .
OS Platform: Ubuntu
Description: Ubuntu 16.04.2 LTS
Release: 16.04
Codename: xenial
1. 虚拟环境构建(为什么需要使用虚拟环境?)
使用虚拟环境安装Flask,可以避免包的每个项目之间的程序扩展包混乱和版本的冲突,虚拟环境是Python解释器的副本,在虚拟环境中你可以针对每个项目安装对应的扩展包,为每个程序单独创建的虚拟环境,可以保证程序只能访问虚拟环境中的包。而不会影响系统中安装的全局Python解释器,从而保证全局解释器的整洁。
虚拟环境使用virtualenv创建,可以查看系统是否安装了virtualenv:
$ virtualenv --version
安装虚拟环境(须在联网状态下)
$ sudo pip install virtualenv
$ sudo pip install virtualenvwrapper
安装完虚拟环境后,如果提示找不到mkvirtualenv命令,须配置环境变量:
# 1、创建目录用来存放虚拟环境
mkdir $HOME/.virtualenvs
# 2、打开~/.bashrc文件,并添加如下:
exportWORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
# 3、运行
source ~/.bashrc
创建虚拟环境(ubuntu里须在联网状态下, "py2"提定的是基于Python2开发的项目)
$ mkvirtualenv Flask_py2
进入虚拟环境
$ workon Flask_py2
退出虚拟环境
如果所在环境为真实环境,会提示deactivate:未找到命令
$ deactivate Flask_py
2.安装Flask
指定Flask版本安装
$ pip install flask==0.10.1
Mac系统:
$ easy_install flask==0.10.1
1.2.2安装Flask依赖包
安装依赖包(须在虚拟环境中):依赖就是开发以及程序运行需要使用的环境的集合。包括软件、插件等。
我们一般会把需要使用的依赖给保存在一个文件中,命名为requirements的txt文件。
如果在其它环境中要运行我们的项目,直接通过指令可以一次性安装所有依赖。
安装依赖包(须在虚拟环境中):
(Flask_py2)...$ pip install -rrequirements.txt
(注:有了requirement.txt文件后,你如果再创建新项目时,可以通过上面的命令快速部署一个相同环境的Flask项目的运行系统,不需要再一个包一个包去安装, 并且自动去配置好Flask,在整个项目完成后,建议生成一份最终的requirement.txt文件,一旦灾难恢复可以快速部署完成环境.)
生成依赖包记录文件(须在虚拟环境中执行):
(Flask_py2)...$ pip freeze >requirements.txt
在ipython中测试安装是否成功
$ from flask import Flask
Flask视图(Views)学习
Flask程序运行过程分析:
所有Flask程序必须有一个程序实例。
Flask调用视图函数后,会将视图函数的返回值作为响应的内容,返回给客户端。一般情况下,响应内容主要是字符串和状态码。
当客户端想要获取资源时,一般会通过浏览器发起HTTP请求。此时,Web服务器使用WSGI(Web Server Gateway Interface)协议,把来自客户端的所有请求都交给Flask程序实例。WSGI是为Python 语言定义的Web服务器和Web应用程序之间的一种简单而通用的接口,它封装了接受HTTP请求、解析HTTP请求、发送HTTP,响应等等的这些底层的代码和操作,使开发者可以高效的编写Web应用。
程序实例使用Werkzeug来做路由分发(URL请求和视图函数之间的对应关系)。根据每个URL请求,找到具体的视图函数。 在Flask程序中,路由的实现一般是通过程序实例的route装饰器实现。route装饰器内部会调用add_url_route()方法实现路由注册。
调用视图函数,获取响应数据后,把数据传入HTML模板文件中,模板引擎负责渲染响应数据,然后由Flask返回响应数据给浏览器,最后浏览器处理返回的结果显示给客户端。
示例:新建文件hello.py:
#coding:utf-8
# 导入Flask类
from flaskimport Flask
# Flask类接收一个参数__name__
app = Flask(__name__)
# 装饰器的作用是将路由映射到视图函数index
@app.route('/')
defindex():
return'Hello MyWorld'
# Flask应用程序实例的run方法启动WEB服务器
if __name__ =='__main__':
app.run()
给路由传参示例:
有时我们需要将同一类URL映射到同一个视图函数处理,
比如:使用同一个视图函数来显示不同用户的个人信息。
# 路由传递的参数默认当做string处理,这里指定int,尖括号中冒号后面的内容是动态的,可自已指定一个数值.
@app.route('/user/<int:id>')
defhello_baidu(id):
return'hellobaidu %d' % id
abort函数:
如果在视图函数执行过程中,出现了异常错误,我们可以使用abort函数立即终止视图函数的执行。通过abort函数,可以向前端返回一个http标准中存在的错误状态码,表示出现的错误信息。
使用abort抛出一个http标准中不存在的自定义的状态码,没有实际意义。如果abort函数被触发,其后面的语句将不会执行。其类似于python中raise。
from flaskimportFlask,abort
@app.route('/')
defhello_baidu():
abort(404)
return'hellobaidu',999
捕获异常:
在Flask中通过装饰器来实现捕获异常,errorhandler()接收的参数为异常状态码。视图函数的参数,返回的是错误信息。
@app.errorhandler(404)
deferror(e):
return'页面不存在,请确认后再次访问!%s'%e
重定向redirect示例
from flaskimport redirect
@app.route('/')
defhello_baidu():
return redirect('http://www.baidu.com')
abort函数:
如果在视图函数执行过程中,出现了异常错误,我们可以使用abort函数立即终止视图函数的执行。通过abort函数,可以向前端返回一个http标准中存在的错误状态码,表示出现的错误信息。
使用abort抛出一个http标准中不存在的自定义的状态码,没有实际意义。如果abort函数被触发,其后面的语句将不会执行。其类似于python中raise。
from flaskimportFlask,abort
@app.route('/')
defhello_baidu():
abort(404)
return'hellobaidu',999
捕获异常:
在Flask中通过装饰器来实现捕获异常,errorhandler()接收的参数为异常状态码。视图函数的参数,返回的是错误信息。
@app.errorhandler(404)
deferror(e):
return'页面不存在,请确认后再次访问!%s'%e
重定向redirect示例
from flaskimport redirect
@app.route('/')
defhello_baidu():
return redirect('http://www.baidu.com')
正则URL示例:
正则URL是为了匹配指定的URL,而匹配指定的URL则可以达到限制访问,以及优化访问路径的目的。
from flaskimport Flask
from werkzeug.routingimport BaseConverter
classRegex_url(BaseConverter):
def__init__(self,url_map,*args):
super(Regex_url,self).__init__(url_map)
self.regex = args[0]
app =Flask(__name__)
app.url_map.converters['re'] = Regex_url
@app.route('/user/<re("[a-z]{3}"):id>')
defhello_baidu(id):
return'hello %s' %id
设置cookie和获取cookie
例一:
from flaskimport Flask,make_response
@app.route('/cookie')
defset_cookie():
resp = make_response('This is to set cookie')
resp.set_cookie('username','baidu')
return resp
例二:
from flaskimport Flask,request
#获取cookie
@app.route('/request')
defresp_cookie():
resp = request.cookies.get('username')
return resp
2.2扩展
上下文:相当于一个容器,保存了Flask程序运行过程中的一些信息。
Flask中有两种上下文,请求上下文和应用上下文。
请求上下文(request context)
request和session都属于请求上下文对象。
request:封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get('user'),获取的是get请求的参数。
session:用来记录请求会话中的信息,针对的是用户信息。举例:session['name']= user.id,可以记录用户信息。还可以通过session.get('name')获取用户信息。
应用上下文(application context)
current_app和g都属于应用上下文对象。
current_app:表示当前运行程序文件的程序实例。
我们可以通过current_app.name打印出当前应用程序实例的名字。
g:处理请求时,用于临时存储的对象,每次请求都会重设这个变量。比如:我们可以获取一些临时请求的用户信息。
· 当调用app = Flask(_name_)的时候,创建了程序应用对象app;
· request在每次http请求发生时,WSGI server调用Flask.call();然后在Flask内部创建的request对象;
· app的生命周期大于request和g,一个app存活期间,可能发生多次http请求,所以就会有多个request和g。
· 最终传入视图函数,通过return、redirect或render_template生成response对象,返回给客户端。
区别: 请求上下文:保存了客户端和服务器交互的数据。 应用上下文:在flask程序运行过程中,保存的一些配置信息,比如程序文件名、数据库的连接、用户信息等。
请求钩子
在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:在请求开始时,建立数据库连接;在请求结束时,指定数据的交互格式。为了让每个视图函数避免编写重复功能的代码,Flask提供了通用设施的功能,即请求钩子。
请求钩子是通过装饰器的形式实现,Flask支持如下四种请求钩子:
before_first_request:在处理第一个请求前运行。
before_request:在每次请求前运行。
after_request:如果没有未处理的异常抛出,在每次请求后运行。
teardown_request:在每次请求后运行,即使有未处理的异常抛出。
Flask装饰器路由的实现:
Flask有两大核心:Werkzeug和Jinja2。Werkzeug实现路由、调试和Web服务器网关接口。Jinja2实现了模板。
Werkzeug是一个遵循WSGI协议的python函数库。其内部实现了很多Web框架底层的东西,比如request和response对象;与WSGI规范的兼容;支持Unicode;支持基本的会话管理和签名Cookie;集成URL请求路由等。
Werkzeug库的routing模块负责实现URL解析。不同的URL对应不同的视图函数,routing模块会对请求信息的URL进行解析,匹配到URL对应的视图函数,以此生成一个响应信息。
routing模块内部有Rule类(用来构造不同的URL模式的对象)、Map类(存储所有的URL规则)、MapAdapter类(负责具体URL匹配的工作);
Flask-Script扩展命令行
通过使用Flask-Script扩展,我们可以在Flask服务器启动的时候,通过命令行的方式传入参数。而不仅仅通过app.run()方法中传参,比如我们可以通过python hello.pyrunserver --host ip地址,告诉服务器在哪个网络接口监听来自客户端的连接。默认情况下,服务器只监听来自服务器所在计算机发起的连接,即localhost连接。
我们可以通过pythonhello.py runserver --help来查看参数。
from flaskimport Flask
from flask_scriptimport Manager
app = Flask(__name__)
manager = Manager(app)
@app.route('/')
defindex():
return'天上的星星亮晶晶'
if __name__ =="__main__":
manager.run()