如何使用 FastAPI 获取 Jinja2 模板中更新的项目列表?
- 2025-02-05 13:24:00
- admin 原创
- 61
问题描述:
我正在我的博客上建立一个评论系统,并且我正在呈现现有的评论,如下所示:
{% for comment in comments %}
<div id="task-comments" class="pt-4">
<!-- comment-->
<div
class="bg-white rounded-lg p-3 flex flex-col justify-center items-center md:items-start shadow-lg mb-4">
<div class="flex flex-row justify-center mr-2">
<img alt="avatar" width="48" height="48"
class="rounded-full w-10 h-10 mr-4 shadow-lg mb-4"
src="https://cdn1.iconfinder.com/data/icons/technology-devices-2/100/Profile-512.png">
<h3 class="text-purple-600 font-semibold text-lg text-center md:text-left ">{{
comment.author['name']|e }}</h3>
</div>
<p style="width: 90%" class="text-gray-600 text-lg text-center md:text-left ">{{
comment.content|e }} </p>
</div>
<!-- comment end-->
<!-- comment-->
<!-- comment end-->
</div>
{% endfor %}
这里的问题是,当我发表评论(使用 FastAPI 路由)时,我不知道如何获取更新的评论列表。我知道 Jinja 可能不是最好的工具,并考虑过使用 Alpine JS x-for 循环,但我很想知道是否有办法在 Jinja 中原生执行此操作。
谢谢!!
解决方案 1:
这听起来像是WebSockets的一个用例。下面的示例基于上述文档链接中给出的示例,可以处理多个连接,将任何新添加的评论广播给所有连接的客户端。因此,如果您http://127.0.0.1:8000/
在浏览器中打开多个选项卡,并使用其中一个连接添加新评论,则其他每个连接/客户端也将收到您刚刚添加的新评论。如果您不想广播消息,您可以改用await manager.send_personal_message(data, websocket)
。
工作示例
应用程序
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
from websockets.exceptions import ConnectionClosed
from fastapi.templating import Jinja2Templates
import uvicorn
class ConnectionManager:
def __init__(self):
self.active_connections: List[WebSocket] = []
async def connect(self, websocket: WebSocket):
await websocket.accept()
self.active_connections.append(websocket)
def disconnect(self, websocket: WebSocket):
self.active_connections.remove(websocket)
async def send_personal_message(self, message: str, websocket: WebSocket):
await websocket.send_json(message)
async def broadcast(self, message: str):
for connection in self.active_connections:
await connection.send_json(message)
class Comment:
def __init__(self, author, content):
self.author = author
self.content = content
app = FastAPI()
templates = Jinja2Templates(directory="templates")
manager = ConnectionManager()
comments = []
comments.append( Comment("author 1 ", "content 1") )
comments.append( Comment("author 2 ", "content 2") )
comments.append( Comment("author 3 ", "content 3") )
@app.get("/")
def main(request: Request):
return templates.TemplateResponse("index.html", {"request": request, "comments": comments})
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await manager.connect(websocket)
try:
while True:
data = await websocket.receive_json()
comments.append(Comment(data['author'], data['content']))
await manager.broadcast(data)
except (WebSocketDisconnect, ConnectionClosed):
manager.disconnect(websocket)
if __name__ == '__main__':
uvicorn.run(app, host='127.0.0.1', port=8000)
模板/index.html
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Add new comment</h1>
<form action="" onsubmit="addComment(event)">
<input type="text" id="author" autocomplete="off"/>
<input type="text" id="content" autocomplete="off"/>
<button>Add comment</button>
</form>
<h2>Comments</h2>
<ul id='comments'>
{% for comment in comments %}
<li>
<h3> {{comment.author}} </h3>
<p> {{comment.content}} </p>
</li>
{% endfor %}
</ul>
<script>
var ws = new WebSocket("ws://localhost:8000/ws");
ws.onmessage = function(event) {
var comments = document.getElementById('comments')
var comment = document.createElement('li')
var jsonObj = JSON.parse(event.data);
var authorNode = document.createElement('h3');
authorNode.innerHTML = jsonObj.author;
var contentNode = document.createElement('p');
contentNode.innerHTML = jsonObj.content;
comment.appendChild(authorNode);
comment.appendChild(contentNode);
comments.appendChild(comment)
};
function addComment(event) {
var author = document.getElementById("author")
var content = document.getElementById("content")
ws.send(JSON.stringify({"author": author.value, "content": content.value}))
author.value = ''
content.value = ''
event.preventDefault()
}
</script>
</body>
</html>
相关推荐
热门文章
项目管理软件有哪些?
热门标签
云禅道AD