1. 我们学习Flask框架,开始的时候是把所有的视图函数等都写在一个文件中
我们在这单个文件中可以定义路由、视图函数、定义模型等等。
但这显然存在一个问题:随着业务代码的增加,将所有代码都放在单个程序文件中,是非常不合适的。
这不仅会让代码阅读变得困难,而且会给后期维护带来麻烦。
2. 问题怎么解决呢
一个程序执行文件中,功能代码过多。 让代码实现模块化
尝试用模块的导入的方式解决
把一个文件拆开,把视图函数按照不同的功能进行划分,分成不同的文件,然后建立一个主文件,在主文件中。利用模块导入的方法,
这是我的文件目录
可以在其他文件里面把视图函数放出去,然后利用装饰器传入参数的方式进行在主文件中把其他视图的路由进行绑定
from flask import Flask from Blueprint_le.goods import get_goods from Blueprint_le.users import register # 循环引用,解决的方法,推迟一方的导入,让一方先完成 # 使用装饰器的函数使用方法,解决模块分割的问题 app = Flask(__name__) app.route("/get_goods")(get_goods) app.route("/register")(register) @app.route("/") def index(): return "index page" if __name__ == '__main__': print(app.url_map) app.run()
3. 什么是蓝图?
蓝图:用于实现单个应用的视图、模板、静态文件的集合。
蓝图就是模块化处理的类。
简单来说,蓝图就是一个存储操作路由映射方法的容器,主要用来实现客户端请求和URL相互关联的功能。
在Flask中,使用蓝图可以帮助我们实现模块化应用的功能。
4.蓝图的运行机制:
蓝图是保存了一组将来可以在应用对象上执行的操作。
注册路由就是一种操作,当在程序实例上调用route装饰器注册路由时,这个操作将修改对象的url_map路由映射列表。
当我们在蓝图对象上调用route装饰器注册路由时,它只是在内部的一个延迟操作记录列表defered_functions中添加了一 个项。当执行应用对象的 register_blueprint() 方法时,应用对象从蓝图对象的 defered_functions 列表中取出每一项,即 调用应用对象的 add_url_rule() 方法,这将会修改程序实例的路由映射列表。
5.蓝图的使用
(1)创建蓝图对象
'''Blueprint必须指定两个参数,admin表示蓝图的名称,__name__表示蓝图所在模块''' admin = Blueprint('admin',__name__)
(2) 注册蓝图的路由
@admin.route('/') def admin_index(): return 'admin_index'
(3) 在程序中注册该蓝图
app.register_blueprint(admin,url_prefix='/admin')
6.蓝图的使用例子
以目录的形式定义蓝图以及蓝图里面模板目录的处理
1. 首先我的目录结构和我的程序和模板存放的目录为:
2. 使用目录分割,在cart目录里面的_ _ init _ _.py里面创建蓝图,并且要把视图加载进来
from flask import Blueprint '''创建蓝图 修改模板路径为当前templates的路径,还有一个设置静态的目录static_folder''' app_cart = Blueprint("app_cart", __name__, template_folder="templates") '''在__init__.py执行的时候,把视图加载进来,让蓝图与应用程序知道有视图的存在''' # Blueprint_le.cart.views : 从路径里面的views.py导入get_cart视图函数 from Blueprint_le.cart.views import get_cart
3. 在views.py里面使用蓝图,定义视图函数,
定义模板 cart.html存放在cart里面的templates下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>cart page</h1> </body> </html>
views.py
from flask import render_template from Blueprint_le.cart import app_cart @app_cart.route("/get_cart") def get_cart(): return render_template("cart.html")
4.不使用目录的分割形式也可以,例如建立order.py,建立蓝图
from flask import Blueprint '''创建一个蓝图的对象,蓝图就是一个小模块的抽象的模块''' app_orders = Blueprint("app_orders", __name__) @app_orders.route("/get_orders") def get_orders(): return "get orders page"
5.然后建立一个main.py在里面实现主要的代码:
from flask import Flask from Blueprint_le.orders import app_orders from Blueprint_le.cart import app_cart app = Flask(__name__) '''注册蓝图 , url_prefix:给访问的路径加一个前缀''' app.register_blueprint(app_orders, url_prefix="/orders") app.register_blueprint(app_cart, url_prefix="/cart") @app.route("/") def index(): return "index page" if __name__ == '__main__': # 打印出所有的路由 print(app.url_map) app.run(debug=True)
6. 首先可以访问 没有使用目录分割的orders, 运行程序,浏览器访问 127.0.0.1:5000/orders/get_orders
然后可以访问使用目录分割的cart,浏览器访问 127.0.0.1:5000/cart/get_cart
7. 如果蓝图里面的小目录里面没有找到模板,则会去顶级的templates的目录里面去找
如果在蓝图的小目录的templates的模板和总的templates的模板重名的话,则会使用总的templates里的模板