在循环中更新 Jinja 变量
Updating Jinja Variable in loop
所以我正在我的博客上构建一个评论系统,并呈现像这样的现有评论L
{% 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 %}
这里的问题是,当我 post 发表评论时(使用 fastapi 路由)- 我不知道如何获取更新的评论列表!我知道 Jinja 可能不是最好的工具,并且考虑过使用 Alpine JS x-for 循环......但很想知道 Jinja 是否有办法在本地执行此操作。
谢谢!!
这听起来像是 WebSockets. The below is based on the example given in the documentation above, and can handle multiple connections, broadcasting the newly added comment to all the connected clients. Thus, if you open http://127.0.0.1:8000/ 在浏览器的多个选项卡中的一个用例,并使用其中一个连接添加新评论,其他每个人也会收到新评论。如果您不想广播消息,则可以改用 await manager.send_personal_message(data, websocket)
.
app.py
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
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:
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>
所以我正在我的博客上构建一个评论系统,并呈现像这样的现有评论L
{% 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 %}
这里的问题是,当我 post 发表评论时(使用 fastapi 路由)- 我不知道如何获取更新的评论列表!我知道 Jinja 可能不是最好的工具,并且考虑过使用 Alpine JS x-for 循环......但很想知道 Jinja 是否有办法在本地执行此操作。
谢谢!!
这听起来像是 WebSockets. The below is based on the example given in the documentation above, and can handle multiple connections, broadcasting the newly added comment to all the connected clients. Thus, if you open http://127.0.0.1:8000/ 在浏览器的多个选项卡中的一个用例,并使用其中一个连接添加新评论,其他每个人也会收到新评论。如果您不想广播消息,则可以改用 await manager.send_personal_message(data, websocket)
.
app.py
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
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:
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>