在 Flask 或 Tornado 中返回渲染后的页面内容,主要涉及模板渲染和异步处理。以下是两种框架的实现方法:
1. Flask 方案(同步)
Flask 使用 Jinja2 模板引擎渲染页面:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
# 渲染 templates/index.html,传递变量
return render_template('index.html', title='首页', message='欢迎!')
if __name__ == '__main__':
app.run(port=5000)
文件结构:
project/
├── app.py
└── templates/
└── index.html <-- 模板文件
模板示例 (templates/index.html
):
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ message }}</h1>
</body>
</html>
2. Tornado 方案(异步)
Tornado 内置异步支持和模板引擎:
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
async def get(self):
# 模拟异步操作(如数据库查询)
data = await self.fetch_data()
# 渲染模板并传递数据
self.render("index.html", title="首页", items=data)
async def fetch_data(self):
# 示例异步函数(实际替换为数据库调用等)
return ["项目1", "项目2", "项目3"]
def make_app():
return tornado.web.Application(
handlers=[(r"/", MainHandler)],
template_path="templates" # 模板目录
)
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
模板示例 (templates/index.html
):
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>列表内容:</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% end %}
</ul>
</body>
</html>
关键点说明:
特性 | Flask | Tornado |
---|---|---|
渲染方法 | render_template('模板名', 变量) |
self.render('模板名', 变量) |
模板目录 | 默认 ./templates |
需手动指定 template_path |
异步支持 | 需扩展(如 Quart) | 原生支持异步 async/await |
适用场景 | 传统同步应用 | 高并发、长连接(WebSocket) |
常见问题解决:
模板路径错误:
- 确保模板文件在
templates
目录内 - Tornado 需在
Application
中指定template_path="templates"
- 确保模板文件在
变量未渲染:
- 检查模板中的变量名
{{ var }}
是否和 Python 代码中传递的名称一致
- 检查模板中的变量名
Tornado 异步操作:
- 使用
async def get()
定义异步处理器 - 在 I/O 操作前加
await
(如数据库查询)
- 使用
根据需求选择框架:
- 简单 CRUD 应用 → Flask 更快捷
- 高并发/实时应用 → Tornado 更合适