请求钩子hook
类似Django中的中间件
1、处理第一个请求前执行 @app.before_first_request def handle(): pass 2、处理每个请求前执行 @app.before_request def handle(): pass 3、处理每个请求后执行,视图函数没有出现异常执行 @app.after_request def handle(response): return response 4、处理每个请求后执行,视图函数是否出现异常都执行, 非调试模式debug=False @app.teardown_request def handle(response): return response
使用
python app.py runserver -h 0.0.0.0 -p 8000
python app.py shell
jinja2模板
1、渲染
from flask import render_template data = { "name": "python", "age": 18, "my_dict": {"city": "beijing"}, "my_list": [1, 2, 3, 4, 5], } render_template("index.html", **data)
变量 {{ name }}
字典 {{ my_dict.city }} {{ my_dict[“city”] }}
列表 {{ my_list[0] }}
数字相加 {{ 1 + 2 }}
字符串拼接 {{ “hello” + “world” }}
2、 字符串过滤器(支持链式调用 )
safe 禁用转义 xss攻击
capitalize 首字母大写,其他小写
lower 转小写
upper 转大写
title 每个单词首字母大写
trim 首尾空格去掉
reverse 反转字符串
format 格式化输出(类似%格式化)
striptags 删除html标签
3、列表过滤器
first 取第一个元素
last 取最后一个元素
length 获取列表长度
sum 列表求和
sort 列表排序
4、自定义过滤器
方式一:
(1)定义过滤器 def list_step_2(lst): return lst[::2] (2)注册过滤器 app.add_template_filter(list_step_2, "list_step_2") (3)使用过滤器 {{ lst | list_step_2 }}
方式二:
@app.template_filter("list_step_2") def list_step_2(lst): return lst[::2]
模板宏macro
1、不带参数宏
{% macro input() %} <input type="text" > {% endmacro %} {{ input() }}
2、带参数宏
{% macro input(type) %} <input type="{{type}}" > {% endmacro %}
3、带默认参数宏
{% macro input(type="text") %} <input type="{{type}}" > {% endmacro %}
4、导入宏
{% import "macro.html" as my_macro%} {{ my_macro.input() }}
模板继承
bash.html
{% block top%} 父模板的内容 {% endblock %}
child.html
{% extends "bash.html" %} {% block top%} 子模板的内容 {% endblock %}
模板包含
{% inclued "hello.html" %}
Flask中的特殊变量
可以直接在模板中使用
config
request
url_for
get_flashed_messages基于session
from flask import flash flash("hello1") flash("hello2") {% for msg in get_flashed_messages() %} {{msg}} {% endfor %}
Flask-Script扩展
pip install Flask-Script
Manager 启动命令管理类
from flask import Flask from flask_script import Manager app = Flask(__name__) #创建app管理类 manager = Manager(app) @app.route("/") def index(): pass if __name__ == "__main__": # app.run() manager.run()
表单扩展
pip install Flask-WTF
可以进行csrf验证 表单生成 和 验证
Flask数据库扩展
pip install Flask-SQLAlchemy
Flask数据库迁移扩展
pip install Flask-Script (依赖) pip install Flask-Migrate
Flask发送邮件
pip install Flask-Mail
循环导入-死锁
解决:一方让步,延迟导入
路由设置的方式
1、装饰器 @app.route("/") def view(): pass 2、装饰器原始方式 def view(): pass app.route("/")(view)
蓝图Blueprint
一个小模块的抽象概念, 延迟加载
1、定义蓝图
# __init__.py from flask import Blueprint # 工程目录的优先级大于应用目录 app_user = Blueprint("app_user", __name__, template_folder="templates") # init执行的时候把视图加载进来 from .views import view
2、定义视图
# views.py from . import app_user @app_user.route("/") def view(): pass
3、注册蓝图
# main.py from flask import Flask app = Flask(__name__) app.register_blueprint(app_user, url_prefix="/user")
4、查看路由
app.url_map
单元测试
web开发阶段:
需求分析,设计阶段,实现阶段,测试阶段
测试阶段
单元测试,集成测试,系统测试
断言assert
-真 继续执行
-假 抛出异常 AssertionError
Flask单元测试
app.test_client()
测试数据库
开启->测试->断开
Flask部署
pip install gunicorn
gunicorn -w 4 // 进程数 -b 127.0.0.1:5000 // 开启端口 --access-logfile ./logs //日志文件 -D // 守护进程方式运行 main:app // 要运行的程序入口
ps aux|grep gunicorn
Nginx
负载均衡
静态文件
cp nginx.conf nginx.conf.bak
upstream flask{ server 10.0.0.1:5000; server 10.0.0.1:5001; } server{ listion 80; server_name localhost; location / { proxy_pass http://flask; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr }
平滑重启 nginx -s reload
mysql异常
@@tx_isolation
修改报错文件base.py
# cursor.execute("SELECT @@tx_isolation") if self.server_version_info < (5, 7, 20): cursor.execute("SELECT @@tx_isolation") else: cursor.execute("SELECT @@transaction_isolation")