You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于蓝图视图的Flask Jinja模板条件判断实现方法问询

解决方案

当然可以实现,下面是几种高效的方式,不用为每个路由单独设置变量,也不需要创建多个base.html文件:

方法1:利用请求上下文g对象 + 蓝图before_request钩子

在目标蓝图中注册一个前置请求钩子,将蓝图标识存入g对象,之后在base.html中通过判断这个标识来渲染不同导航栏:

蓝图代码示例

from flask import Blueprint, g

# 定义管理员蓝图
admin_bp = Blueprint('admin', __name__, url_prefix='/admin')

@admin_bp.before_request
def set_admin_context():
    # 给g对象添加当前蓝图的标识
    g.current_blueprint = 'admin'

# 蓝图的路由示例
@admin_bp.route('/dashboard')
def dashboard():
    return render_template('admin/dashboard.html')

base.html模板代码

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <!-- 根据当前蓝图渲染不同导航栏 -->
    {% if g.get('current_blueprint') == 'admin' %}
        <nav class="admin-nav">
            <a href="{{ url_for('admin.dashboard') }}">管理面板</a>
            <a href="{{ url_for('admin.manage_users') }}">用户管理</a>
        </nav>
    {% else %}
        <nav class="default-nav">
            <a href="{{ url_for('main.index') }}">首页</a>
            <a href="{{ url_for('main.about') }}">关于我们</a>
        </nav>
    {% endif %}

    {% block content %}{% endblock %}
</body>
</html>

方法2:全局上下文处理器自动注入蓝图信息

更简洁的方式是通过Flask的上下文处理器,自动将当前请求所属的蓝图名注入到所有模板中,无需在每个蓝图里写钩子:

应用层代码

from flask import Flask, request

app = Flask(__name__)

@app.context_processor
def inject_blueprint_data():
    # request.blueprint会自动返回当前请求对应的蓝图名称(无蓝图则为None)
    return {'current_blueprint': request.blueprint}

base.html模板代码

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    {% if current_blueprint == 'admin' %}
        <!-- 管理员导航栏 -->
        <nav>
            <a href="{{ url_for('admin.dashboard') }}">管理面板</a>
            <a href="{{ url_for('admin.manage_users') }}">用户管理</a>
        </nav>
    {% elif current_blueprint == 'shop' %}
        <!-- 商城蓝图的导航栏 -->
        <nav>
            <a href="{{ url_for('shop.product_list') }}">商品列表</a>
            <a href="{{ url_for('shop.cart') }}">购物车</a>
        </nav>
    {% else %}
        <!-- 默认导航栏 -->
        <nav>
            <a href="{{ url_for('main.index') }}">首页</a>
            <a href="{{ url_for('main.about') }}">关于我们</a>
        </nav>
    {% endif %}

    {% block content %}{% endblock %}
</body>
</html>

方法3:给蓝图自定义导航配置(更灵活)

如果需要为每个蓝图定义独立的导航项列表,可以直接给蓝图对象添加自定义属性,再通过上下文处理器传递到模板:

蓝图代码示例

from flask import Blueprint

admin_bp = Blueprint('admin', __name__, url_prefix='/admin')
# 给管理员蓝图自定义导航项
admin_bp.nav_items = [
    ('管理面板', 'admin.dashboard'),
    ('用户管理', 'admin.manage_users'),
    ('系统设置', 'admin.settings')
]

shop_bp = Blueprint('shop', __name__, url_prefix='/shop')
shop_bp.nav_items = [
    ('商品列表', 'shop.product_list'),
    ('购物车', 'shop.cart'),
    ('订单中心', 'shop.orders')
]

应用层上下文处理器

from flask import request, current_app

@app.context_processor
def inject_navigation():
    # 获取当前蓝图对象
    if request.blueprint:
        current_bp = current_app.blueprints.get(request.blueprint)
        # 优先使用蓝图自定义的导航项,没有则用默认
        nav_items = getattr(current_bp, 'nav_items', [
            ('首页', 'main.index'),
            ('关于我们', 'main.about')
        ])
    else:
        nav_items = [
            ('首页', 'main.index'),
            ('关于我们', 'main.about')
        ]
    return {'nav_items': nav_items}

base.html模板代码

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <!-- 统一渲染导航栏,无需判断蓝图 -->
    <nav>
        {% for label, endpoint in nav_items %}
            <a href="{{ url_for(endpoint) }}">{{ label }}</a>
        {% endfor %}
    </nav>

    {% block content %}{% endblock %}
</body>
</html>

以上三种方式都能满足你的需求:只需在蓝图层面配置一次,无需修改每个路由,也不用维护多个base.html文件。

内容的提问来源于stack exchange,提问作者Jimmy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:05:31