为什么使用蓝图
Blueprint 是一种组织一组相关视图及其他代码的方式。与把视图及其他 代码直接注册到应用的方式不同,蓝图方式是把它们注册到蓝图,然后在工厂函数中 把蓝图注册到应用。
Flask 中蓝图有以下用途:
- 把一个应用分解为一套蓝图。这是针对大型应用的理想方案:一个项目可以实例化 一个应用,初始化多个扩展,并注册许多蓝图。
- 在一个应用的 URL 前缀和(或)子域上注册一个蓝图。 URL 前缀和(或)子域的 参数成为蓝图中所有视图的通用视图参数(缺省情况下)。
- 使用不同的 URL 规则在应用中多次注册蓝图。
- 通过蓝图提供模板过滤器、静态文件、模板和其他工具。蓝图不必执行应用或视图 函数。
- 当初始化一个 Flask 扩展时,为以上任意一种用途注册一个蓝图。
**Flask 中的蓝图不是一个可插拨的应用,因为它不是一个真正的应用,而是一套可以 注册在应用中的操作,并且可以注册多次。那么为什么不使用多个应用对象呢?可以 使用多个应用对象(参见 **应用调度 ),但是这样会导致每个应用都使 用自己独立的配置,且只能在 WSGI 层中管理应用。
而如果使用蓝图,那么应用会在 Flask 层中进行管理,共享配置,通过注册按需改 变应用对象。蓝图的缺点是一旦应用被创建后,只有销毁整个应用对象才能注销蓝图。
创建并使用蓝图
假如我们现在要创建一个用户蓝图,则在应用主目录(app)中创建一个名为user的python包,在此包下创建一个view.py的文件,在此文件中创建用户蓝图。代码如下:
from flask import Blueprint
user_bp = Blueprint('user', __name__, url_prefix='/user')
@user_bp.route('/')
def user_center():
return '用户中心'
创建蓝图后,需要在工厂函数中使用register_blueprint()注册蓝图,让蓝图绑定在app实例下,如下:
from flask import Flask
def create_app():
app = Flask(__name__)
# app = Flask(__name__, template_folder='../templates', static_folder='../static') 若不移动模板和静态文件目录,则需要指明模板和静态文件夹
# 加载配置文件
app.config.from_object('yourapplication.default_settings')
# 注册蓝图
app.register_blueprint(user_bp)
return app
值得注意的是,当我们创建了一个蓝图并使用后(写了一些视图函数),想在重定向时需使用url_prefix的值点上视图函数的名称
例如我注册了一个文章蓝图,发布文章后给浏览器返回一个重定向响应,重定向到文章列表页面,我的文章列表视图函数为article_list,那么重定向时需使用return redirect(url_for('article.article_list'))
from .model import Article, ArticleCategory, Comment
from apps.user.model import User
from ..exts import db
from flask import Blueprint, render_template, request, redirect, g, url_for
from ..user.decorators import login_required
article_bp = Blueprint('article', __name__, url_prefix='/article')
@article_bp.route('/article_list/')
def article_list():
articles = Article.query.order_by(-Article.create_time)
return render_template('article/article_list.html', articles=articles)
@login_required
@article_bp.route('/post_article/', methods=['GET', 'POST'])
def post_article():
if request.method == 'GET':
article_categories = ArticleCategory.query.all()
return render_template('article/post_article.html', article_categories=article_categories)
else:
title = request.form.get('title')
category_id = request.form.get('article_category')
content = request.form.get('content')
author_id = g.user.id
article = Article(title=title, category_id=category_id, content=content, author_id=author_id)
db.session.add(article)
db.session.commit()
return redirect(url_for('article.article_list'))
评论区 0