Flask记录(1)
Flask框架的诞生:
Flask诞生于2010年,是Armin ronacher(人名)用Python语言基于Werkzeug工具箱编写的轻量级Web开发框架。
Flask本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login),都需要用第三方的扩展来实现。比如可以用Flask-extension加入ORM、窗体验证工具,文件上传、身份验证等。Flask没有默认使用的数据库,你可以选择MySQL,也可以用NoSQL。
其 WSGI 工具箱采用 Werkzeug(路由模块),模板引擎则使用 Jinja2。这两个也是Flask框架的核心。
Python最出名的框架要数Django,此外还有Flask、Tornado等框架。虽然Flask不是最出名的框架,但是Flask应该算是最灵活的框架之一,这也是Flask受到广大开发者喜爱的原因。
Flask常用扩展包:
- Flask-SQLalchemy:操作数据库;
- Flask-migrate:管理迁移数据库;
- Flask-Mail:邮件;
- Flask-WTF:表单;
- Flask-Bable:提供国际化和本地化支持,翻译;
- Flask-script:插入脚本;
- Flask-Login:认证用户状态;
- Flask-OpenID:认证;
- Flask-RESTful:开发REST API的工具;
- Flask-Bootstrap:集成前端Twitter Bootstrap框架;
- Flask-Moment:本地化日期和时间;
- Flask-Admin:简单而可扩展的管理接口的框架
Flask 安装环境
虚拟环境使用virtualenv创建,可以查看系统是否安装了virtualenv:
$ virtualenv --version
安装虚拟环境
$ sudo pip install virtualenv
$ sudo pip install virtualenvwrapper
使用虚拟环境
进入虚拟环境
$ deactivate Flask_py
安装Flask
指定Flask版本安装 $ pip install flask==0.10.1 pip freeze > requirements.txt
requirements 文件
Python 项目中必须包含一个 requirements.txt 文件,用于记录所有依赖包及其精确的版本号,以便在新环境中进行部署操作。
在虚拟环境使用以下命令将当前虚拟环境中的依赖包以版本号生成至文件中:
$ pip freeze >requirements.txt
安装requirements文件内的环境:
$ pip install -r requirements.txt
从 Hello World 开始
Flask程序运行过程
- 所有Flask程序必须有一个程序实例。
- 当客户端想要获取资源时,一般会通过浏览器发起HTTP请求。
- 此时,Web服务器使用WSGI(Web Server Gateway Interface)协议,把来自客户端的所有请求都交给Flask程序实例,程序实例使用Werkzeug来做路由分发(URL请求和视图函数之间的对应关系)。
- 根据每个URL请求,找到具体的视图函数并进行调用。
- 在Flask程序中,路由的实现一般是通过程序实例的装饰器实现。
- Flask调用视图函数后,可以返回两种内容:
- 字符串内容:将视图函数的返回值作为响应的内容,返回给客户端(浏览器)
- HTML模版内容:获取到数据后,把数据传入HTML模板文件中,模板引擎负责渲染HTTP响应数据,然后返回响应数据给客户端(浏览器)
示例:
from flask import Flask #Flask函数接收一个参数name,它会指向程序所在的模块 app = Flask(__name__) #装饰器的作用是将路由映射到视图函数index @app.route('/') def index(): return 'Hello World' #Flask应用程序实例的run方法启动WEB服务器 if __name__ == '__main__': app.run()
- 在程序运行过程中,程序实例中会使用
url_map
将装饰器路由和视图的对应关系保存起来,打印结果如下图:
初始化参数
- import_name: 模块名
- static_url_path: 静态文件访问前缀
- static_folder: 默认‘static’
- template_folder: 默认‘templates’
配置参数
- app.config.from_pyfile() # 从配置文件中加载
- app.config.from_object() # 从对象中加载
- app.config.from_envvar() # 从环境变量中加载
读取配置参数
- app.config.get()
- 在视图中 current_app.config.get()
app.run的参数
- app.run(host=”0.0.0.0”, port=5000, debug = True)
1.6 路由的各种定义方式
请求方式限定
使用 methods 参数指定可接受的请求方式,可以是多种
@app.route('/',methods=['GET']) def hello(): return '<h1>hello world</h1>'
路由查找方式
同一路由指向两个不同的函数,在匹配过程中,至上而下依次匹配
@app.route('/') def hello(): return '<h1>hello world</h1>' @app.route('/') def hello_2017(): return '<h1>hello 2017</h1>'
所以上面路由 /
输出的结果为 hello 函数的结果
给路由传参示例
有时我们需要将同一类URL映射到同一个视图函数处理,比如:使用同一个视图函数 来显示不同用户的个人信息。
路由传递的参数默认当做string处理,这里指定int,尖括号中的内容是动态的,也可不指定类型
@app.route('/user/<int:id>') def hello_baidu(id):
return 'hello itcast %d' %id
重定向redirect示例
from flask import redirect,url_for @app.route('/') def hello_baidu(): return redirect('http://www.baidu.cn')
@app.route('/demo1') def demo1(): # 重定向到外网 # return redirect('http://www.itcast.cn') # 重定向到内部路由 # return redirect('/') # 重定向使用反向解析 : url_for('index') == '/' return redirect(url_for('index'))
返回JSON
from flask import Flask,json @app.route('/json') def do_json(): hello = {"name":"stranger", "say":"hello"} return json.dumps(hello)
返回状态码示例
在 Python 中返回状态码有两种方式实现:
- 直接return
- 可以自定义返回状态码,可以实现不符合http协议的状态码,例如:error=666,errmsg='查询数据库异常',其作用是为了实现前后端数据交互的方便
- abort方法
- 只会抛出符合http协议的异常状态码,用于手动抛出异常
@app.route('/') def hello_baidu(): return 'hello baidu',666
正则路由示例
在web开发中,可能会出现限制用户访问规则的场景,那么这个时候就需要用到正则匹配,限制访问,优化访问
- 导入转换器包
from werkzeug.routing import BaseConverter
-
自定义转换器并实现
# 自定义转换器 class Regex_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>') def hello_itheima(id): return 'hello %s' %id
自带几种转换器
DEFAULT_CONVERTERS = { 'default': UnicodeConverter, 'string': UnicodeConverter, 'any': AnyConverter, 'path': PathConverter, 'int': IntegerConverter, 'float': FloatConverter, 'uuid': UUIDConverter, }
1.7 异常捕获
abort 方法
抛出一个给定状态代码的 HTTPException,例如想要用一个页面未找到异常来终止请求,你可以调用 abort(404)。
参数: code – HTTP的错误状态码
只能抛出HTTP协议的状态码
# abort(404) abort(500)
errorhandler 装饰器
注册一个错误处理程序,当程序抛出指定错误状态码的时候,就会调用该装饰器所装饰的方法
参数:code_or_exception – HTTP的错误状态码或指定异常
- 例如统一处理状态码为500的错误给用户友好的提示:
@app.errorhandler(500) def internal_server_error(e): return '服务器搬家了'
开启调试模式
if __name__ == '__main__': app.run(debug=True)