00:00

文章目录

加载目录中...

Flask创建使用蓝图

为什么使用蓝图

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