文章内容如有错误或排版问题,请提交反馈,非常感谢!
FastAPI 完全可以接入模板引擎来开发传统网站!虽然 FastAPI 以构建高性能 API 著称,但它基于 Starlette 框架,天然支持模板渲染和静态文件托管。

模板引擎选型
| 引擎 | 特点 | 安装命令 |
| Jinja2 | 语法简洁,广泛使用 | pip install jinja2 |
| Mako | 高性能,支持嵌入 Python | pip install mako |
| Chameleon | XML 风格,适合复杂模板 | pip install chameleon |
推荐使用 Jinja2(与 FastAPI 集成最方便)
Jinja2 集成步骤
项目结构
.
├── main.py
├── templates/
│ ├── index.html
│ └── includes/
│ └── header.html
└── static/
├── css/
└── js/
安装依赖
pip install jinja2
配置模板引擎
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
app = FastAPI()
# 挂载静态文件目录
app.mount("/static", StaticFiles(directory="static"), name="static")
# 初始化模板引擎
templates = Jinja2Templates(directory="templates")
基础模板渲染
创建模板文件 templates/index.html
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<link rel="stylesheet" href="{{url_for('static', path='/css/style.css')}}">
</head>
<body>
<h1>{{message}}</h1>
</body>
</html>
路由渲染模板
@app.get("/")
async def read_root(request: Request):
return templates.TemplateResponse(
"index.html",
{
"request": request, # 必须包含 request 对象
"title": "首页",
"message": "欢迎使用 FastAPI!"
}
)
高级模板功能
模板继承
templates/base.html:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
{% block head %}{% endblock %}
</head>
<body>
{% include "includes/header.html" %}
{% block content %}{% endblock %}
</body>
</html>
templates/page.html:
{% extends "base.html" %}
{% block title %}子页面{% endblock %}
{% block content %}
<h1>这是子页面内容</h1>
{% endblock %}
循环和条件
<ul>
{% for item in items %}
<li {% if loop.first %}class="first"{% endif %}>
{{ item.name }} - {{ item.price }}
</li>
{% endfor %}
</ul>
{% if user %}
<p>欢迎回来,{{ user.username }}!</p>
{% else %}
<p>请先登录</p>
{% endif %}
表单处理
模板 templates/form.html
<form method="post"> <input type="text" name="username" required> <input type="password" name="password" required> <button type="submit">登录</button> </form>
路由处理
from fastapi import Form
@app.get("/login")
async def login_form(request: Request):
return templates.TemplateResponse("form.html", {"request": request})
@app.post("/login")
async def do_login(
username: str = Form(...),
password: str = Form(...)
):
# 验证逻辑
return {"username": username}
异步支持
FastAPI 支持在路由中异步渲染模板:
@app.get("/async-page")
async def async_demo(request: Request):
# 模拟异步操作(如数据库查询)
data = await fetch_data_from_db()
return templates.TemplateResponse("async.html", {"request": request, "data": data})
自定义过滤器
#在模板引擎初始化后添加
def reverse_filter(s: str):
return s[::-1]
templates.env.filters["reverse"] = reverse_filter
模板中使用:
<p>{{"hello"|reverse}}</p><!--输出olleh-->
错误页面处理
from fastapi.exceptions import HTTPException
@app.exception_handler(404)
async def not_found_exception_handler(request: Request, exc: HTTPException):
return templates.TemplateResponse(
"404.html",
{"request": request},
status_code=404
)
性能优化
- 模板缓存:Jinja2默认启用缓存,生产环境无需额外配置。
- 静态文件CDN:通过 mount 托管静态文件,或使用Nginx/CDN加速。
- 异步渲染:对I/O密集型操作(如数据库查询)使用 async/await 避免阻塞。
模板预加载
#在应用启动时预编译模板
@app.on_event("startup")
async def preload_templates():
templates.env.compile_templates(
"templates",
"compiled_templates.zip"
)
异步渲染(需要第三方扩展)
#使用 jinja2.asyncenv.AsyncEnvironment
from jinja2 import FileSystemLoader
from jinja2.asyncenv import AsyncEnvironment
async_templates = AsyncEnvironment(
loader=FileSystemLoader("templates"),
enable_async=True
)
@app.get("/async-page")
async def async_page(request: Request):
template = async_templates.get_template("async_page.html")
content = await template.render_async(request=request)
return HTMLResponse(content)
完整示例
from fastapi import FastAPI, Request, Form
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
@app.get("/")
async def home(request: Request):
return templates.TemplateResponse(
"index.html",
{
"request": request,
"users": [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25}
]
}
)
@app.get("/contact")
async def contact(request: Request):
return templates.TemplateResponse(
"contact.html",
{"request": request}
)
@app.post("/submit-form")
async def submit_form(
name: str = Form(...),
email: str = Form(...)
):
return {"name": name, "email": email}
最佳实践
- 模板组织:
- 使用 includes/ 目录存放可复用组件
- 通过 html 实现模板继承
- 静态文件管理:
- 使用 url_for(‘static’, path=’…’) 生成静态文件URL
- 为CSS/JS添加版本号防止缓存
- 安全注意事项:
- 启用Jinja2自动转义:autoescape=True
- 避免直接渲染用户输入内容
- 开发热重载:
templates = Jinja2Templates(
directory="templates",
auto_reload=True #开发环境启用
)
通过以上步骤,可以轻松在FastAPI中实现动态页面渲染。建议根据项目复杂度选择合适的功能组合,小型项目使用基础模板渲染即可,复杂项目可结合模板继承和自定义过滤器等功能。
局限性及替代方案
- 适用性:
- ✅适合简单页面或混合模式(API+少量页面)。
- ❌复杂前端交互建议搭配前端框架(如React/Vue)。
- 替代方案:
- 纯API模式:FastAPI只提供数据,前端使用 js/Nuxt.js渲染。
- 全栈框架:若需更多内置功能(如ORM、Admin后台),可考虑Django。
通过集成Jinja2模板引擎,FastAPI可快速实现服务端渲染的网站开发,同时保留其异步高性能特性。适合轻量级全栈项目或需要API与页面混合交付的场景。对于复杂前端,建议采用前后端分离架构,用FastAPI专注提供API服务。



