Table of Contents
不使用蓝图进行模块划分
01循环引用
Flask的App与项目同级,蓝图是小的应用模块划分
flask没有将视图,url,model分开,如启动主程序main
from flask import Flask app = Flask(__name__) @app.route('/') def welcome(): return 'index page' |
将其中一个视图拿出,还会用到app对象:
from main import app @app.route('/register',methods=['GET','POST']) def register(): form=RegisterForm() if form.validate_on_submit(): user_name=form.user_name.data print(user_name) session["user_name"]=user_name return redirect(url_for("index")) return render_template('register.html',form=form) |
此时主程序不知道有其他模块存在,需要导入:
from users import register |
此时会发生循环引用(类似于线程死锁),使其中一方推迟导入,让另一方先完成,将main中的视图导入放到其中一个函数的定义中:
@app.route('/') def welcome(): from users import register |
02装饰器解决模块分割
导入的模块装饰器需要使用app,从该装饰过程中入手,在导入文件中只定义参数不装饰
# from main import app #@app.route('/register',methods=['GET','POST']) def register(): form=RegisterForm() if form.validate_on_submit(): user_name=form.user_name.data print(user_name) session["user_name"]=user_name return redirect(url_for("index")) return render_template('register.html',form=form) |
将装饰过程放在主程序进行:
app.route('/register',methods=['GET','POST'])(register) |
这个传参看着有点诡异,@代表将下方的函数作为参数传入,此处同样放入函数名
如简单装饰器为2层闭包:
def itcast(func): def inner(): pass return inner |
@itcast def register(): |
等同于
itcast(register) |
带参数的装饰器,相当于三层闭包:
def route(params): def decorator(func): def inner(): pass return inner return decorator |
其中,route('/register',methods=['GET','POST'])为最外层闭包传入参数,(register)为内层闭包传入的函数引用
使用蓝图进行模块划分
01蓝图定义
路由不再绑定再app上,而是绑定在蓝图对象,实现完成后,在app实例注册蓝图
导入蓝图:
from flask import Blueprint |
创建蓝图对象,蓝图就是模块的抽象。最少2参数,蓝图名与控制范围
app_orders=Blueprint("app_orders",__name__) |
使用:
@app_orders.route("/get_orders") def get_orders(): |
在主程序注册:
app.register_blueprint(app_orders) |
02目录形式定义
由蓝图延迟加载
在主程序中注册,前缀设置:
app.register_blueprint(app_orders,url_prefix="/orders") |
包名初始化文件__init__.py中定义
from flask import Blueprint app_orders=Blueprint("app_orders",__name__) |
在此文件夹新建py定义视图函数,从包内导入,在init中定义的属性也可找到
from . import app_orders |
@app_orders.route("/get_orders") |
导入app_orders包时,init文件会执行,此时把蓝图加载进来。在__init__中
from .views import get_orders |
03蓝图模板目录处理
蓝图以目录结构定义后,目录可自成一套体系,也可以定义小的静态文件夹、模板文件夹
在orders目录中:
from flask import render_template from .views import get_orders |
@app_orders.route("/get_orders") def get_orders(): return render_template('order.html') |
Init中Blueprint("app_orders",__name__)配置的__name__用来寻找文件目录
需要显式指明静态文件位置
app_orders=Blueprint("app_orders",__name__, static_folder="static", template_folder="templates") |
order.html可放到该文件夹的templates中
指明后,该文件夹没有,也会在总文件夹的静态目录找