1,环境安装
1, mkvirtualenv name -p python3
2, pip install flask==1.0.3
环境变量配置:一般不用,只用在部署项目时,
export FLASK_APP=xx.py # 指定flask应⽤所在的⽂件路径 export FLASK_ENV=development # 设置项⽬的环境, 默认是⽣产环境 flask run -h 0.0.0.0 -p 8000 # 启动测试服务器并接受请求
2,路由定义
1,路由一定要以‘/’开头 2,可以通过app.url_map属性来获取所有路由(url资源段) 3,可以通过method 方法指定参数来设置路由的请求方式 自定义路由转换器 1,自定义路由转换器类,继承BaseConverter 2,定义属性regex,设置匹配规则 3,添加自定义转换器
示例代码:
from flask import Flask app = Flask(__name__) # 1. URL必须以/开头 # 3. 可以通过methods参数来设置路由支持的请求方式 @app.route('/index', methods=['POST', 'GET']) def index(): return "index" if __name__ == '__main__': # 2.可以通过app.url_map属性来获取所有的路由规则 (URL资源段 支持的请求方式 视图函数的标记) print(app.url_map) # for rule in app.url_map.iter_rules(): # print(rule.rule, rule.methods, rule.endpoint) app.run(debug=True)
3,路由变量
正则对路由变量进行格式过滤,失败会返回404,
# 路由变量: 实现动态URL 让一个视图函数可以绑定"一类URL" # 获取某本书 GET /books/(?P<pk>d+) # 路由变量格式: /user/<路由变量的名称> from flask import Flask from werkzeug.routing import BaseConverter app = Flask(__name__) # @app.route('/user/<userid>') # def index(userid): # 一旦定义了路由变量, 必须定义同名形参来接收路由变量的值 # print(userid) # return "index" # 正则转换器: 对路由变量进行格式过滤 过滤失败会返回404 # 格式: /user/<转换器名:路由变量> @app.route('/user/<int:userid>') # int转换器: 要求路由变量必须能够转为int def user(userid): print(type(userid)) return 'user'
自定义转换器的使用:
1. 自定义转换器类 继承BaseConverter
2. 定义属性regex, 设置匹配规则
3. 添加自定义转换器
# 所有的内置转换器都继承BaseConverter """自定义转换器 1. 自定义转换器类 继承BaseConverter 2. 定义属性regex, 设置匹配规则 3. 添加自定义转换器 """ class MobileConverter(BaseConverter): # 自定义转换器类 # 定义属性regex, 设置匹配规则 regex = r'1[3-9]d{9}$' # 规则不要添加开头的^ # 添加自定义转换器 {转换器名: 转换器类} app.url_map.converters['mob'] = MobileConverter @app.route('/home/<mob:mobile>') # 使用自定义的转换器 def home(mobile): return 'home' if __name__ == '__main__': # 获取所有的转换器 {转换器名: 转换器类} # print(app.url_map.converters) app.run(debug=True)
4,flask接收前端的4中方式
1,查询字符串方式 request.args
# 获取查询字符串 -> request.args 类字典对象 # print(request.args.get('name'))
2,获取form_data表单传参 request.form
# 获取请求体-键值对(表单) -> request.form 类字典对象 # print(request.form.get('username'))
3,获取请求体传参 文本 request.data | request.json
# 获取请求体-文本(json) -> request.data/request.json # print(request.data) # bytes类型 # print(request.json.get('name')) # 会将json字符串自动转为字典
4,获取请求体传参 文件 request.files
# 获取请求体-文件(图片) -> request.files 类字典对象 file = request.files.get('avatar') # type: FileStorage # 将文件保存到本地 # file.save('123.png') # 获取文件的二进制数据 file_bytes = file.read()
完整代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from flask import Flask, request from werkzeug.datastructures import FileStorage app = Flask(__name__) @app.route('/', methods=['POST', 'GET']) def index(): # 获取请求的URL # print(request.url) # 获取本次请求的请求方式 # print(request.method) # 获取本次请求的请求头 # print(request.headers) # 类字典对象 可以像字典一样赋值和取值 # print(request.headers.get('Host')) # 建议使用get方法, 不存在会返回None, 不报错 # 请求传递数据的方式 1> URL路径参数-> 路由变量 2> GET 查询字符串 xx?name=xx&age=20 3> POST 请求体 键值对(表单)/文本(json)/文件(图片) 4> 请求头 -> request.headers # 获取查询字符串 -> request.args 类字典对象 # print(request.args.get('name')) # 获取请求体-键值对(表单) -> request.form 类字典对象 # print(request.form.get('username')) # 获取请求体-文本(json) -> request.data/request.json # print(request.data) # bytes类型 # print(request.json.get('name')) # 会将json字符串自动转为字典 # 获取请求体-文件(图片) -> request.files 类字典对象 file = request.files.get('avatar') # type: FileStorage # 将文件保存到本地 # file.save('123.png') # 获取文件的二进制数据 file_bytes = file.read() print(file_bytes) return "index" if __name__ == '__main__': app.run(debug=True)
响应:
1,访问静态文件步骤:
1,将静态文件放入static文件夹中
2,使用flask内置的静态文件路由进行访问 http://127.0.0.1:5000/static/s.jpg
from flask import Flask app = Flask(__name__) if __name__ == '__main__': app.run(debug=True)
注意:只要在与当前同级目录下建立static文件,然后将图片文件放入该文件加下,启动程序,访问/static/xxx.jpg便可以
2, 后端模板渲染步骤:
1,将模板放入template文件夹中,指定模板语言
2,使用render_template函数进行渲染
3,在模板语言中使用模板语言来替换
@app.route('/',methods=["GET"]) def index(): keyword = 'hello' html_str = render_template('baidu.html',kw=keyword) return html_str
template文件中html代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 你输入的内容为: {{ kw }} </body> </html>
3,自定义响应对象 (需要设置响应头的时候才使用自定义响应对象)
@app.route('/demo1')
def demo1():
# 视图函数可以返回str、bytes类型数据,并且内部会自动包装为Response类型的响应对象
# 1,创建自定义响应对象,需要设置响应头的时候
response = make_response('demo1')
# 2,设置响应头, 类字典对象
response.headers['name'] = 'xxx'
return response
4,返回json数据 jsonify会将字典封装为json对象,并且将content_type设置为application/json (访问浏览器进行测试)
# 4, 返回json @app.route('/demo2') def demo2(): dict = {'name':'sd'} #jsonify可以将字典,关键字参数封装成json对象返回给前端,并且将content_type设置为application/json return jsonify(dict)
5,重定向 :设置响应状态为301/302,响应头Location:目标url
def demo3(): # return redirect('http://www.baidu.com') # return redirect('/demo2') #直接访问本网站 # 可以根据视图函数的变偶记获取对应的url的资源段 # url = url_for('demo2') #根据函数名找到对应的url # print(url) # 开发中一般这样使用,考虑url重构 # return redirect(url_for('demo2')) url = url_for('demo4',userid = 11) #传递的参数,先使用url_for获取访问函数demo4的url,然后进行重定向(可以拼接参数) return redirect(url) @app.route('/demo4/<userid>') def demo4(userid): return 'demo4_%s'%userid
6,自定义状态码:return的三段参数(响应体,响应状态码,响应头)
# 6自定义状态码 @app.route('/demo5') def demo5(): #设置自定义状态,第二个返回值,用于自定义交互规则,700密码错误等 # return 三段参数 (响应体,状态码,响应头) # return ‘demo5’,700,{'name':'xxx'} return 'demo5',700
7,状态保持(session和cookie)
1,cookie
from flask import Flask, make_response, Response, request app = Flask(__name__) @app.route('/') def index(): # 后端设置cookie: 设置响应头的set_cookie字段 # 创建响应对象 response = make_response('index') # type: Response # 设置响应头 value值必须是str/bytes response.set_cookie('per_page', '10', max_age=86400) # 删除cookie数据 本质: max-age=0 # response.delete_cookie('per_page') return response @app.route('/demo1') def demo1(): # 获取cookie: 浏览器会自动携带cookie数据给服务器, 通过请求头的cookie字段 per_page = request.cookies.get('per_page') # 类字典对象 print(per_page) return 'demo1'
2,session (flask的session默认是存储在浏览器的cookie中的)
from datetime import timedelta from flask import Flask, session app = Flask(__name__) # 设置应用秘钥 用于对session数据进行签名 app.secret_key = 'test' # 设置session的过期时间 默认为31天 app.permanent_session_lifetime = timedelta(days=7) @app.route('/') def index(): # 记录session数据 类字典对象 session['userid'] = 11 # 设置session支持过期时间 session.permanent = True return "index" @app.route('/demo') def demo(): # 获取session数据 print(session.get('userid')) # 删除session数据 本质:max_age=0 设置过期时间为0 session.pop('userid', None) return 'demo'
if __name__ == '__main__': app.run(debug=True)
注意:flask的session默认是存储在浏览器的session中的,只是经过简单的base64进行加密,使用时一般都要修改存储位置:设置方式如下
from datetime import timedelta from flask import Flask, session from flask_session import Session from redis import StrictRedis app = Flask(__name__) # 设置session的配置 app.config['SESSION_TYPE'] = 'redis' # 设置存储系统 app.config['SESSION_REDIS'] = StrictRedis(host='127.0.0.1', port=6379) # 指定redis客户端 app.config['SESSION_USE_SIGNER'] = True # 设置对session进行签名 app.config['SECRET_KEY'] = 'test' # 设置应用秘钥 # 初始化组件 Session(app) @app.route('/') def index(): # 记录session数据 类字典对象 session['userid'] = 11 return "index" @app.route('/demo') def demo(): # 获取session数据 print(session.get('userid')) # 删除session数据 # session.pop('userid', None) return 'demo' if __name__ == '__main__': app.run(debug=True
8,flask对象初始化参数
from flask import Flask import sys # 记录模块的查询路径 包含 项目目录, 解释器目录, 第三方包的安装目录 print(sys.path) app = Flask(__name__, # 导入名称, flask会根据该参数查询静态/模板文件存储路径 # 官方建议直接使用__name__, 如果使用该值, 则会从当前文件所在的目录中查询静态/模板文件存储路径 static_folder='static1', # 设置静态文件的存储路径 , static_url_path='/res/img', # 设置静态文件的访问路径 /res/img/oldyang.jpg template_folder='templates' # 设置模板文件的存储路径 ) @app.route('/') def index(): return "index" print(index.__name__) if __name__ == '__main__': app.run(debug=True)
9,异常
请求钩子(相当于django的中间件)
@app.before_first_request(第一个访问web应用会触发,初始化处理)
@app.teardown_request(响应对象包装为Response对象后触发,无论是否异常都会触发,相当于fanilly)
蓝图:
上下文:
装饰器wraps的使用:因为引用发生了变化
flask的配置:
通过app.config
动态创建应用 ,(添加蓝图创建应用)
缺点:重要配置容易泄露
从环境变量中加载:
先从对象中加载默认配置,再通过环境变量重载隐私配置