Flask入门
Flask入门WEB工作原理Flask框架flask_script扩展蓝本(blueprint)
WEB工作原理
C/S和B/S架构 c:client s:server b:browser s:server
B/S工作原理
客户端(浏览器) <=> WEB服务器(nginx/apache) <=> Python(Flask) <=> 数据库(MySQL)
Flask框架
简介
是一个非常小的python web框架,被称为微型框架,只提供了一个强健的核心,其它的功能都要使用扩展来实现。意味着可以根据自己的项目需求量身打造。遵循BSD证书。
官网 http://flask.pocoo.org/
附各种证书说明:
组成
调试、路由、WSGI系统
模板引擎(Jinja2,Flask的核心人员开发)
安装
mkvirtualenv -p C:\Users\My\AppData\Local\Programs\Python\Python36\python.exe flaskenv
pip install flask -i https://pypi.douban.com/simple/
Flask 依赖两个外部库: Jinja2 模板引擎和 Werkzeug WSGI 套件
第一个程序
# 导入Flask类库
fromflaskimportFlask
# 创建应用实例
app=Flask(__name__)
# 创建视图函数
@app.route('/')
defindex():
return'Hello Flask !'
# 启动应用实例
if__name__=='__main__':
app.run()
默认访问地址:http://127.0.0.1:5000
启动参数
参数说明
debug是否开启调试模式,开启后有错误提示,代码修改后可以重新启动
threaded开启多线程,默认是不开启的
port指定端口号
host指定主机,设置为‘0.0.0.0’后可以通过ip地址进行访问
请求与响应
变量或对象
什么是“上下文”
一个单独的存储区域,接收和调用到各个范围传递过来的属性,这就是所谓的”上下文“
Flask中的上下文
为了避免大量可有可无的参数把视图函数弄得一团糟,Flask使用上下文临时把某些对象变为“全局访问”
变量/对象上下文说明
current_app程序上下文当前运行的程序实例
g(global的简写)程序上下文处理请求时用作临时存储的对象,专门用来保存用户数据,每次请求都会重置,g对象在一次请求中的所有代码中都是可以使用的。
request请求上下文请求对象,保存了客户端的所有的HTTP请求信息
session请求上下文用户会话,用于保存需要'记住'的会话信息
这里的request属于请求上下文,请求对象,封装了客户端发出的HTTP请求中的内容,距离说明:假设前端使用ajax带参数 data:{a:b} 请求一个后端接口,我们用Python写的后端接口就可以使用request这个“全局变量”来获取ajax的请求数据,如果接口是post,put类型,则可以使用
data = request.form
获取,如果是get请求,则是可以使用
data=request.args
请求钩子函数
fromflaskimportFlask,g
app=Flask(__name__)
@app.route('/test/')
deftest():
returng.string
@app.before_first_request
defbf_first_request():
g.string='before_first_request'
@app.before_request
defbf_request():
g.string='before_request'
# 注册一个函数,没有异常情况下,在每次请求之后运行.
# 注册的函数至少需要含有一个参数
# 这个参数实际上为服务器的响应,且函数中需要返回这个响应参数.
@app.after_request
def af_request(param):
param.set_cookie('username', 'xiaoming')
return param
```
函数描述
before_first_request第一次请求之前
before_request每次请求之前
after_request没有异常情况下,每次请求之后
teardown_request每次请求之后,无论是否有异常,常用于关闭数据库连接
视图函数
不带参数的视图函数,见《完整程序》
带参数的视图函数,如下:
# 带参数的路由,不指定参数类型,默认是字符串
@app.route('/hello//')
defhello(username):
return'Hello %s !'%username
# 参数可以指定类型:int、float、path(/不再是分隔符)
@app.route('/user//')
defuser(uid):
return'%d号用户详细信息'%uid
@app.route('/path//')
defpath(p):
returnp
总结说明
若指定参数,需要将参数外添加<>,且路由参数名称要与视图函数参数一致
参数可以指定类型,如:string、int、float、path,不指定默认为字符串
路由中的最后的'/'最好还是加上
请求(request)
@app.route('/request/')
defreq():
# 完整的请求URL
# return request.url
# 基本路由信息,不包含get参数
#return request.base_url
# 只包含主机和端口
#return request.host_url
# 只包含装饰器中的路由地址
#return request.path
# 请求方法类型
#return request.method
# 客户端IP地址
#return request.remote_addr
# 所有的请求参数(GET)
#return request.args['page']
# 返回一个列表
# returen str(request.args.getlist('username'))
# 请求头信息
returnrequest.headers['User-Agent']
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Mozilla/5.0 :以前用于Netscape浏览器,目前大多数浏览器UA都会带有。
Windows NT 6.1:代表windows7系统。
WOW64:Windows-on-Windows 64-bit,32位的应用程序运行于此64位处理器上。
AppleWebKit/537.36:浏览器内核。
KHTML:一个HTML排版引擎。
like Gecko:这不是Geckeo 浏览器,但是运行起来像Geckeo浏览器。
Chrome/55.0.2883.87:Chrome版本号。
Safari/537.36:宣称自己是Safari?
响应(response)
@app.route('/response/')
defresponse():
# 只要返回字符串就可以,默认状态码为200
#return 'ok'
# 可以指定状态码
#return 'page not found', 404
# 先使用专门的函数构造一个响应,然后返回,可以在构造时指定状态码
resp=make_response('我是提前构造好的响应',404)
returnresp
重定向(redirect)
@app.route('/redirect/')
defnew():
#return 'abc'
#return redirect('/')
# 根据视图函数,反向构造对应的路由,传递的参数是视图函数名
#return redirect(url_for('response'))
# 可以拼接路由参数,多余的参数会以get方式拼接在url后面
#return redirect(url_for('hello', username='xiaoming', page=2))
# 当需要构造外部跳转的链接时,需要将_external设置为True以构造完整路由
returnurl_for('hello',username='xx',_external=True)
url_for('hello') ==>/hello/
url_for('hello',_external=True) ==>http://127.0.0.0:5000/hello/
终止(abort)
@app.route('/abort/')
deferr():
# 使用abort不是说控制权归调用的函数所有,
# 而是向系统抛出一个异常,按照系统原有的异常处理方式进行处理
abort(404)
return'error'
# 定制错误显示页面
@app.errorhandler(404)
defpage_not_found(e):
return'老铁,有木有搞错'
课堂练习:定制一个500的错误显示页面。
会话控制(cookie/session)
# 设置cookie
@app.route('/set_cookie/')
defset_cookie():
resp=make_response('cookie已设置')
expires=time.time()+10
# 设置cookie,顺便可以指定过期时间
resp.set_cookie('name','xiaoming',expires=expires)
returnresp
# 获取cookie
@app.route('/get_cookie/')
defget_cookie():
returnrequest.cookies.get('name')or'你是哪个二哥'
# 设置秘钥,此处的秘钥不只是用于session的加密
app.config['SECRET_KEY'] ='123456'
# 设置session
@app.route('/set_session/')
defset_session():
session['username'] ='xiaoma'
return'session已设置'
# 获取session
@app.route('/get_session/')
defget_session():
returnsession.get('username','who are you?')
flask_script扩展
安装:pip install flask-script
说明:
在项目测试完成后,上线时最好不要改动任何代码。只能通过终端的方式进行启动,通过传递不同的参数,完成特定的启动方式。很遗憾flask默认不支持命令行启动,然而幸运(^_^)的是有一个第三方库flask-script帮我们实现了这个功能。简单来说,它就是一个flask终端启动的命令行解析器。
使用:
# 导入类库
fromflask_scriptimportManager
# 创建对象
manager=Manager(app)
# 启动应用实例
if__name__=='__main__':
#app.run(debug=True, threaded=True, port=8000, host='0.0.0.0')
manager.run()
启动参数
-?,--help # 查看帮助信息
--threaded # 开启多线程
-d # 开启调试模式
-r # 自动加载
-h,--host # 指定主机
-p,--port # 指定端口
在命令行使用
python manage.py runserver -d -r -p 8000 -h 0.0.0.0
蓝本(blueprint)
说明:
代码越来越复杂时,将所有的视图函数放在一个文件中是很不合理的,如果能够根据功能不同将特定的视图函数分类存放,蓝本就是为了解决这个问题而出现的
使用:
# 导入类库
fromflaskimportBlueprint
# 创建对象
user=Blueprint('user',__name__)
@user.route('/register/')
defregister():
return'欢迎注册'
在manage.py中注册蓝本。
# 蓝本注册,不注册时蓝本处于休眠状态
app.register_blueprint(user,url_prefix='/user')