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

Flask Jinja2模板中session无法调用的问题排查求助

问题:Flask模板中session未定义,无法访问session.yesOrNo

我搭建了一个小型测试项目,预期首次访问页面时显示"maybe",之后能将值存入session并在模板中使用。

项目结构

$ find * | grep -v __
app.py
pages
pages/app_main.html
requirements.txt

app.py代码

import sys

from dotenv import dotenv_values
from flask import Flask, session
from jinja2 import Environment, PackageLoader

cfg = dotenv_values(".env")

sys.path.append(f"{cfg['APP_HOME']}")

app = Flask(__name__)
app.config["SESSION_TYPE"] = "filesystem"
app.secret_key = b'aae14431-9269-4322-958e-7dbb4474bf7a'
application = app 
env = Environment(loader=PackageLoader('app', 'pages'))


@app.route("/")
def app_main():
    main = env.get_template('app_main.html')
    session['yesOrNo'] = 'maybe'
    context = dict()
    print(f"the yesOrNo value is {session.get('yesOrNo')}")
    return main.render(**context)


@app.route("/setyes")
def app_yes():
    main = env.get_template('app_main.html')
    session['yesOrNo'] = 'yes'
    context = dict()
    return main.render(**context)

@app.route("/setno")
def app_no():
    main = env.get_template('app_main.html')
    session['yesOrNo'] = 'no'
    context = dict()
    return main.render(**context)


if __name__ == '__main__':
    app.run()

模板文件pages/app_main.html代码

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
    <title>App</title>
</head>
<body>
<div>
    <p>{{ session.yesOrNo }}</p>
</div>
</body></html>

报错信息

* Detected change in '/home/ray/Projects/test_session/app.py', reloading
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 978-769-374
the yesOrNo value is maybe
127.0.0.1 - - [26/Apr/2023 14:27:08] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/ray/.local/lib/python3.10/site-packages/flask/app.py", line 2548, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/ray/.local/lib/python3.10/site-packages/flask/app.py", line 2528, in wsgi_app
    response = self.handle_exception(e)
  File "/home/ray/.local/lib/python3.10/site-packages/flask/app.py", line 2525, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/ray/.local/lib/python3.10/site-packages/flask/app.py", line 1822, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/ray/.local/lib/python3.10/site-packages/flask/app.py", line 1820, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/ray/.local/lib/python3.10/site-packages/flask/app.py", line 1796, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
  File "/home/ray/Projects/test_session/app.py", line 25, in app_main
    return main.render(**context)
  File "/home/ray/.local/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "/home/ray/.local/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "/home/ray/Projects/test_session/pages/app_main.html", line 8, in top-level template code
    <p>{{ session.yesOrNo }}</p>
  File "/home/ray/.local/lib/python3.10/site-packages/jinja2/environment.py", line 485, in getattr
    return getattr(obj, attribute)
jinja2.exceptions.UndefinedError: 'session' is undefined

解答

问题出在你手动初始化了Jinja2的Environment和PackageLoader,这种方式没有把Flask的上下文(比如session对象)注入到模板环境中。Flask自带的render_template函数会自动处理上下文传递,包括session、request等内置对象。

修改方案如下:

  1. 删掉手动创建的Jinja环境相关代码,导入Flask的render_template
  2. 视图函数中改用render_template渲染模板,不需要手动获取模板再调用render
  3. 确保模板文件夹路径符合Flask规则,要么改名为默认的templates,要么在Flask初始化时指定template_folder参数

修改后的app.py代码:

import sys

from dotenv import dotenv_values
from flask import Flask, session, render_template  # 导入render_template

cfg = dotenv_values(".env")

sys.path.append(f"{cfg['APP_HOME']}")

# 指定模板文件夹为pages
app = Flask(__name__, template_folder='pages')
app.config["SESSION_TYPE"] = "filesystem"
app.secret_key = b'aae14431-9269-4322-958e-7dbb4474bf7a'
application = app 

# 移除手动创建Jinja环境的代码
# env = Environment(loader=PackageLoader('app', 'pages'))


@app.route("/")
def app_main():
    session['yesOrNo'] = 'maybe'
    print(f"the yesOrNo value is {session.get('yesOrNo')}")
    return render_template('app_main.html')  # 改用render_template


@app.route("/setyes")
def app_yes():
    session['yesOrNo'] = 'yes'
    return render_template('app_main.html')

@app.route("/setno")
def app_no():
    session['yesOrNo'] = 'no'
    return render_template('app_main.html')


if __name__ == '__main__':
    app.run()

这样修改后,模板里的{{ session.yesOrNo }}就能正常访问session中的值了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:47:40