1.Flask框架学习目标
- 如何编写视图
- 如何处理请求
- 如何构造响应
2.Flask概述
Flask诞生于2010年,是Armin ronacher用Python语言基于Werkzeug工具箱编写的轻量级Web开发框架。Flask本身相当于一个内核,其他几乎所有的功能都需要扩展,都需要用第三方的扩展库来实现。其中的WSGI工具箱采用Werkzeug(路由模块),模板引擎则使用Jinja2,这两个也是Flask框架的核心。
3.框架对比
- 重量级框架:为方便业务程序的开发,提供了丰富的工具、组件,如Django
- 轻量级框架:只提供Web框架的核心功能,自由、灵活、高度定制,如Flask
Flask扩展: - Flask-SQL alchemy:操作数据库;
- Flask_script:插入脚本;
- Flask-migrate:管理迁移数据库;
- Flask-Session:Session存储方式指定;
- Flask-WTF:表单;
- Flask-Mail:邮件;
- Flask-Bable:提供国家化和本地化支持,翻译;
- Flask-Login:认证用户状态;
- Flask-OpenID:认证;
- Flask-RESTful:开发RESTful API的工具;
- Flask-Bootstrap:集成前端Twitter Bootstrap框架;
- Flask-Moment:本地化日期和时间;
- Flask-Admin:简单而可扩展的管理接口的框架
4.Flask文档
- 中文文档:https://docs.jinkan.org/docs/flask/
- 英文文档:htttps://flask.pocoo.org/docs/1.0/
5.工程搭建
5.1 环境安装
常用的虚拟环境和pip的命令:
#虚拟环境
mkvirtualenv #创建虚拟环境
rmvirtualenv #删除虚拟环境
workon #进入虚拟环境、查看所有虚拟环境
deactivate #退出虚拟环境
#pip
pip install #安装依赖包
pip uninstall #卸载依赖包
pip list #查看已安装的依赖包
pip freeze #冻结当前环境的依赖包
配置好虚拟环境后安装flask包:pip install flask
5.2 HelloWorld程序
创建helloworld.py文件:
from flask import Flask
app=Flask(__name__)
@app.route("/")
def index():
return "Hello World!"
if __name__=="__main__":
app.run(host="0.0.0.0",port="9999")
5.3 参数说明
1.Flask对象的初始化参数:
这些参数仅仅设置的是Flask本身的属性,如:flask从哪里读取静态文件、从哪里读取模板文件等。
- import_name:Flask程序所在的包(模块),传入"_name_"即可,其决定Flask在访问静态文件时查找的根路径
- static_url_path:静态文件访问路径,默认为:"/+static_folder"
- static_folder:静态文件存储的文件夹,默认为:"static"
- template_folder:模板文件存储的文件夹,默认为"templates"
2.应用程序配置参数
这些参数设置的是一个web应用工程的相关信息,如:数据库的连接信息、日志的配置信息、自定义的配置信息等。Flask将配置信息保存到了app.config属性中,该属性可以按照字典类型进行操作。
读取:
- app.config.get(name)
- app.config[name]
设置:
- 从配置对象中加载:
即将配置信息抽象成一个类,然后从类中进行加载。app.config.from_object(配置对象)
class DefaultConfig(object):
SECRET_KEY="jdkfjdsfkdjfdkfj"
app=Flask(__name__)
app.config.from_object(DefaultConfig)
- 从配置文件中加载:
即将配置信息书写到一个py文件中,然后从文件中进行加载。app.config.from_pyfile(配置文件)
- 从环境变量中加载:
即通过环境变量值找到配置文件,再读取配置文件的信息。app.config.from_envvar("环境变量名",silent=True)
在实践当中,一般从配置对象中加载默认的配置信息,从环境变量中加载个性化的敏感信息。
3.app.run参数
app.run()会运行flask提供的调试服务器
可以指定运行的主机IP地址、端口、是否开启调试模式
app.run(host="0.0.0.0",port="5000",debug=True)
注:开启调试模式后,程序代码修改后可自动重启服务器;同时在服务器出现相关错误时可以将错误信息返回到前端进行展示。
Flask1.0版之后,调整了开发服务器的启动方式,由代码flask run
进行启动,但在运行前要设置FLASK_APP环境变量为flask的启动实例,设置FLASK_ENV环境变量为production(生产模式,默认)或development(开发模式)。
flask run -h 0.0.0.0 -p 8000
6.路由与蓝图
6.1 查询路由信息
- 命令行方式(终端):
set FLASK_APP=helloworld
flask routes
- 脚本命令方式:
使用app.url_map属性:
for rule in app.url_map.iter_rules():
print(f"{rule.endpoint}-->{rule.rule}")
#可以这样改写
import json
@app.route("/")
def index():
return json.dumps({rule.endpoint:rule.rule for rule in app.url_map.iter_rules()})
6.2 指定请求方式
在Flask中,定义路由其默认的请求方式为:
- GET:获取信息
- OPTIONS:简化版的GET请求,用于询问服务器接口信息的
- HEAD:只返回GET请求处理时的响应头,不返回响应体。
利用methods参数可以指定一个接口的请求方式:
@app.route("/itcast1",methods=["GET","POST"]
def index():
return .....
6.3 蓝图
Blueprint 是一个存储操作方法的容器,这些操作在这个Blueprint 被注册到一个应用之后就可以被调用,Flask 可以通过Blueprint来组织URL以及处理请求。Flask使用Blueprint让应用实现模块化,在Flask中,Blueprint具有如下属性:
- 一个应用可以具有多个Blueprint
- 可以将一个Blueprint注册到任何一个未使用的URL下比如 “/”、“/sample”或者子域名
- 在一个应用中,一个模块可以注册多次
- Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的
- 在一个应用初始化时,就应该要注册需要使用的Blueprint
一个blueprint并不是一个完成应用,它不能独立于应用运行,而必须呀注册到某个应用中。
使用蓝图分为三步:
1.创建一个蓝图对象
user_bp=Blueprint('user',__name__)
2.在这个蓝图对象商进行操作,注册路由、指定静态文件夹、注册模板过滤器等
@user_bp.route("/")
def user_profile():
return "user_profile"
3.在应用对象上注册这个蓝图对象
app.register_blueprint(user_bp)
可以将创建蓝图对象与定义视图放在一个文件中。对于一个打算包含多个文件的蓝图,通常将创建蓝图对象放在python包的--init--.py文件中,同时在最后一行代码中要把视图模块导进来。
7.请求与响应
7.1处理请求
1.url路径参数
@app.route('/users/'>)
def user_info(user_id):
return 'hello user {}'.format(user_id)
此处的<>即是一个转换器,默认为字符串类型,也就是将该位置的数据以字符串格式进行匹配,并以字符串为数据类型、uer_id为参数名传入视图。也可以指定转换器的类型:
@app.route('/users/
也可以自定义转换器(分三步):
1)创建转换器类,保存匹配时的正则表达式
from werkzeug.routing import BaseConverter
class MobileConverter(BaseConverter):
regex=r'1[3-9]\d{9}'
2)将自定义的转换器告知Flask应用
app.url_map.converters['mobile']=MobileConverter
3)在使用转换器的地方定义使用
@app.route('/users/'>)
def user_info(mob_num):
return 'send sms code to {}'.format(mob_num)
2.其他参数
如果想要获取其他地方传递的参数,可以通过Flask提供的request对象来读取。
- request.data 记录请求的数据,并转换为字符串
- request.form 记录请求中的表单数据
- request.args 记录请求中的查询参数
- request.cookies 记录请求中的cookies信息
- request.headers 记录请求中的报文头
- request.method 记录请求使用的http方法
- request.url 记录请求的url地址
- request.files 记录请求上传的文件
例如:要获取请求/articles?channel_id=1中channel_id的参数
form flask import request
@app.route("/articles')
def get_articles():
return request.args.get("channel_id")
例如:客户端上传图片到服务器,并保存到服务器中
from flask import request
@app.route("/upload",methods=['POST'])
def upload_file():
f=request.files['pic']
f.save('./demo.png')
return 'ok'
7.2 处理响应
1.返回模板
使用render_template
方法渲染模板并返回
<-- index.html -->
Title
我的模板html内容
{{ my_str}}
{{ my_int}}
from flask import render_template
@app.route("/")
def index():
mstr="hello"
mint=10
return render_template("index.html", my_str=mstr, my_int=mint)
# return render_template('index.html", **data)
2.重定向
from flask import redirect
@app.route("/demo2")
def demo2():
return redirect("http://www.baidu.com")
3.返回JSON
from flask import jsonify
@app.route("/demo")
def demo():
json_dict={"user_id":10, "user_name": "laowang"}
return jsonify(json_dict)
4.自定义状态码和响应头
1)元组方式:
元组必须是(response,status,headers)的形式,且至少包含一个元素。
@app.route("/demo")
def demo():
return "状态码是666", 666,{'Itcase': "python"}
2)make_response方式:
@app.route("/demo")
def demo():
resp= make_response("测试")
resp.headers['Itcase']="python"
resp.status="404"
return resp
8.Cookie与Session
8.1 Cookie
1)设置
from flask import Flask,make_response
app=Flask(__name__)
@app.route("/cookie")
def set_cookie():
resp=make.response("set cookie ok")
resp.set_cookie("username", "itcase", max_age=3600)
return resp
- 读取
from flask import request
@app.route("/get_cookie")
def get_cookie():
resp=request.cookies.get("username")
return resp
- 删除
from flask import request, make_response
app=Flask(__name__)
@app.route("/cookie")
def set_cookie():
resp=make.response("set cookie ok")
resp.delete_cookie("username")
return resp
8.2 Session
操作session,先要设置secret_key:
class DefaultConfig(object):
secret_key="jkjkljkjkj"
app.config.from_object(DefaultConfig)
form flask import session
@app.route('/set-session')
def set_session():
session["username"]="itcase"
return "set session ok!"
@app.route("/get_session")
def get_session():
return session.get("username")
flask为浏览器session,即session数据经服务器端签名后存在了浏览器中。
9.异常处理
9.1 http异常主动抛出
abort方法将抛出一个给定状态码的HTTPException或者指定响应。
abort(500)
9.2 捕获错误
利用errorhandler装饰器,即注册一个错误处理程序,当程序抛出指定错误状态码时,就会调用该装饰器所装饰的方法。
@app.errothandler(500)
def internal_server_error(e):
return "服务器搬家了!"
@app.errorhandler(ZeroDivisionError)
def zero_division_error(e):
return "除数不能为0!"