如何在提交 HTML 表单后使用 FastAPI 将用户重定向回主页?

How to redirect the user back to the home page using FastAPI, after submitting an HTML form?

我有一个页面有 table 个学生。我添加了一个按钮,允许您向 table 添加新行。为此,我将用户重定向到带有输入表单的页面。

问题是提交完成的表单后,用户转到一个新的空白页面。如何传输完整表单中的数据并将用户重定向回 table?

我刚开始学习网络编程,所以我决定先做一个不使用AJAX技术的实现。

代码:

from fastapi import FastAPI, Form
from fastapi.responses import Response

import json
from jinja2 import Template

app = FastAPI()


# The page with the table
@app.get('/')  
def index():
    students = get_students()  # Get a list of students
    with open('templates/students.html', 'r', encoding='utf-8') as file:
        html = file.read()
    template = Template(html)  # Creating a template with a table

    # Loading a template
    return Response(template.render(students=students), media_type='text/html')


# Page with forms for adding a new entry
@app.get('/add_student')
def add_student_page():
    with open('templates/add_student.html', 'r', encoding='utf-8') as file:
        html = file.read()

    # Loading a page
    return Response(html, media_type='text/html')


# Processing forms and adding a new entry
@app.post('/add')
def add(name: str = Form(...), surname: str = Form(...), _class: str = Form(...)):
    add_student(name, surname, _class)  # Adding student data
    # ???

首先,在您 return jinja2 模板的情况下,您应该 return TemplateResponse,如 documentation. To redirect the user to a specific page, you can use RedirectResponse. Since you do that through a POST (and not GET) method (as shown in your example), a 405 (Method Not Allowed) error would be thrown. However, thanks to @tiangolo, you can change the response status code to status_code=status.HTTP_303_SEE_OTHER and the issue will be resolved. Below is a working example. In case you need to pass path and/or query parameters to your endpoints in the future, please have a look at or this answer 中所示。

from fastapi import FastAPI, Request, Form, status
from fastapi.templating import Jinja2Templates
from fastapi.responses import RedirectResponse

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

# replace with your own get_students() method
def get_students():
    return ["a", "b", "c"]

@app.post('/add')
async def add(request: Request, name: str = Form(...), surname: str = Form(...), _class: str = Form(...)):
    # add_student(name, surname, _class)  # Adding student data
    redirect_url = request.url_for('index')    
    return RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER)    

@app.get('/add_student')
async def add_student_page(request: Request):
    return templates.TemplateResponse("add_student.html", {"request": request})

@app.get('/')
async def index(request: Request):
    students = get_students()  # Get a list of students
    return templates.TemplateResponse("index.html", {"request": request, "students": students})