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

如何在FastAPI中为Handlebars.js模板注入数据并返回HTML响应

在FastAPI中用Handlebars渲染HTML及其他模板引擎实现方案

一、用Python版Handlebars(pybars3)实现后端渲染

1. 安装依赖

pip install pybars3 fastapi uvicorn

2. 调整模板文件(index.html)

移除前端Handlebars编译逻辑,保留纯模板结构:

<!DOCTYPE html>
<html>
<head>
    <title>用户信息</title>
</head>
<body>
    <div class="entry">
        {{#if user}}
            {{#each user}}
            <ul>
                <li>{{first_name}}</li>
                <li>{{last_name}}</li>
                <li>{{fav_lang}}</li>
                <li>{{experience}}</li>
            </ul>
            {{/each}}
        {{/if}}
    </div>
</body>
</html>

注:原数据结构中第二个user对象无first_name/last_name,渲染时会显示空值,可根据需求调整数据结构或模板逻辑。

3. 修改FastAPI路由代码

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import pybars
import os

app = FastAPI()

# 读取并编译Handlebars模板
template_path = os.path.join(os.path.dirname(__file__), "index.html")
with open(template_path, "r", encoding="utf-8") as f:
    template_source = f.read()
compiler = pybars.Compiler()
template = compiler.compile(template_source)

@app.get("/render-to-html", response_class=HTMLResponse)
def read_item(first_name: str, last_name: str, fav_lang: str, exp: int):
    result = {
        "user": [
            {"first_name": first_name, "last_name": last_name},
            {"fav_lang": fav_lang, "experience": exp}
        ]
    }
    # 渲染模板并返回HTML
    rendered_html = template(result)
    return HTMLResponse(content=rendered_html)

如果需要前端渲染(后端返回带数据的页面,由前端JS完成渲染),可修改路由如下:

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import os
import json

app = FastAPI()

template_path = os.path.join(os.path.dirname(__file__), "index.html")
with open(template_path, "r", encoding="utf-8") as f:
    template = f.read()

@app.get("/render-to-html", response_class=HTMLResponse)
def read_item(first_name: str, last_name: str, fav_lang: str, exp: int):
    result = {
        "user": [
            {"first_name": first_name, "last_name": last_name},
            {"fav_lang": fav_lang, "experience": exp}
        ]
    }
    # 将数据注入前端JS上下文
    rendered_template = template.replace(
        'var context = {};',
        f'var context = {json.dumps(result)};'
    )
    return HTMLResponse(content=rendered_template)

此方式无需修改原index.html,前端JS会自动读取注入的数据完成渲染。

二、其他模板引擎实现方案

1. Jinja2(FastAPI官方推荐)

Jinja2是Python生态最常用的模板引擎,FastAPI提供原生支持。

安装依赖

pip install jinja2 fastapi uvicorn

创建templates/index.html模板

<!DOCTYPE html>
<html>
<head>
    <title>用户信息</title>
</head>
<body>
    <div class="entry">
        {% if user %}
            {% for item in user %}
            <ul>
                {% if item.first_name %}<li>{{ item.first_name }}</li>{% endif %}
                {% if item.last_name %}<li>{{ item.last_name }}</li>{% endif %}
                {% if item.fav_lang %}<li>{{ item.fav_lang }}</li>{% endif %}
                {% if item.experience %}<li>{{ item.experience }}</li>{% endif %}
            </ul>
            {% endfor %}
        {% endif %}
    </div>
</body>
</html>

路由代码

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse

app = FastAPI()
templates = Jinja2Templates(directory="templates")

@app.get("/render-to-html", response_class=HTMLResponse)
def read_item(request: Request, first_name: str, last_name: str, fav_lang: str, exp: int):
    result = {
        "user": [
            {"first_name": first_name, "last_name": last_name},
            {"fav_lang": fav_lang, "experience": exp}
        ]
    }
    return templates.TemplateResponse("index.html", {"request": request, **result})

2. Mako模板引擎

Mako是一款灵活轻量的Python模板引擎。

安装依赖

pip install mako fastapi uvicorn

创建templates/index.html模板

<!DOCTYPE html>
<html>
<head>
    <title>用户信息</title>
</head>
<body>
    <div class="entry">
        % if user:
            % for item in user:
            <ul>
                % if 'first_name' in item:
                <li>${item['first_name']}</li>
                % endif
                % if 'last_name' in item:
                <li>${item['last_name']}</li>
                % endif
                % if 'fav_lang' in item:
                <li>${item['fav_lang']}</li>
                % endif
                % if 'experience' in item:
                <li>${item['experience']}</li>
                % endif
            </ul>
            % endfor
        % endif
    </div>
</body>
</html>

路由代码

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from mako.template import Template
import os

app = FastAPI()

template_path = os.path.join(os.path.dirname(__file__), "templates", "index.html")
template = Template(filename=template_path)

@app.get("/render-to-html", response_class=HTMLResponse)
def read_item(first_name: str, last_name: str, fav_lang: str, exp: int):
    result = {
        "user": [
            {"first_name": first_name, "last_name": last_name},
            {"fav_lang": fav_lang, "experience": exp}
        ]
    }
    rendered_html = template.render(**result)
    return HTMLResponse(content=rendered_html)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:15:18