Leo*_*pes 3 html python jinja2 fastapi
我在尝试将值从 HTML 表单<input>元素传递到表单的action属性并将其发送到 FastAPI 服务器时遇到以下问题。
这是 Jinja2 (HTML) 模板的加载方式:
# Test TEMPLATES
@app.get("/test",response_class=HTMLResponse)
async def read_item(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
Run Code Online (Sandbox Code Playgroud)
我的 HTML 表单:
<form action="/disableSubCategory/{{subCatName}}">
<label for="subCatName">SubCategory:</label><br>
<input type="text" id="subCatName" name="subCatName" value=""><br>
<input type="submit" value="Disable">
</form>
Run Code Online (Sandbox Code Playgroud)
我的 FastAPI 端点将在表单操作中调用:
<form action="/disableSubCategory/{{subCatName}}">
<label for="subCatName">SubCategory:</label><br>
<input type="text" id="subCatName" name="subCatName" value=""><br>
<input type="submit" value="Disable">
</form>
Run Code Online (Sandbox Code Playgroud)
我得到的错误:
"GET /disableSubCategory/?subCatName=Barber HTTP/1.1" 404 Not Found
Run Code Online (Sandbox Code Playgroud)
我想要实现的是以下 FastAPI 调用:
/disableSubCategory/{subCatName} ==> "/disableSubCategory/Barber"
Run Code Online (Sandbox Code Playgroud)
谁能帮助我理解我做错了什么?
谢谢。狮子座
您可以将类别名称定义为Form后端中的参数,并使用 HTML 从前端提交 POST 请求,如本答案<form>的方法 1 中所述。
应用程序.py
\nfrom fastapi import FastAPI, Form, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\'templates\')\n\n@app.post(\'/disable\')\ndef disable_cat(cat_name: str = Form(...)):\n return f\'{cat_name} category has been disabled.\'\n\n@app.get(\'/\', response_class=HTMLResponse)\ndef main(request: Request):\n return templates.TemplateResponse(\'index.html\', {\'request\': request})\nRun Code Online (Sandbox Code Playgroud)\n模板/index.html
\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset="utf-8">\n <meta name="viewport" content="width=device-width, initial-scale=1">\n </head>\n <body>\n <h1>Disable a category</h1>\n <form method="post" action="/disable">\n <label for="cat_name">Enter a category name to disable:</label><br>\n <input type="text" id="cat_name" name="cat_name">\n <input class="submit" type="submit" value="Submit">\n </form>\n </body>\n</html>\nRun Code Online (Sandbox Code Playgroud)\n您可以在端点中将类别名称声明为查询参数,并在前端使用与问题中演示的方法类似的方法,将表单元素的值转换<input>为查询参数,然后将其添加到查询字符串中URL 的(在action属性中)。
请注意,与上面相反,下面使用 GET 请求(在这种情况下,您需要@app.get()在后端和<form method="get" ...前端使用,无论如何,这是默认方法)。请注意,大多数浏览器都会缓存 GET 请求(即保存在浏览器的历史记录中),因此与 POST 相比,它们的安全性较低,因为发送的数据是 URL 的一部分,并且对有权访问该设备的任何人都可见。因此,在发送密码或其他敏感信息时不应使用 GET 方法。
应用程序.py
\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\'templates\')\n\n@app.get(\'/disable\')\ndef disable_cat(cat_name: str):\n return f\'{cat_name} category has been disabled.\'\n\n@app.get(\'/\', response_class=HTMLResponse)\ndef main(request: Request):\n return templates.TemplateResponse(\'index.html\', {\'request\': request})\nRun Code Online (Sandbox Code Playgroud)\n模板/index.html
\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset="utf-8">\n <meta name="viewport" content="width=device-width, initial-scale=1">\n </head>\n <body>\n <h1>Disable a category</h1>\n <form method="get" id="myForm" action=\'/disable{{ cat_name }}\'>\n <label for="cat_name">Enter a category name to disable:</label><br>\n <input type="text" id="cat_name" name="cat_name">\n <input class="submit" type="submit" value="Submit">\n </form>\n </body>\n</html>\nRun Code Online (Sandbox Code Playgroud)\n如果您想使用 POST 请求\xe2\x80\x94,这比 GET 更安全,因为参数不存储在浏览器的历史记录中,并且在更新服务器上的内容/状态时更有意义,与请求(而不是修改)数据时应使用的 GET\xe2\x80\x94 相比,您可以定义 FastAPI 端点,并将@app.post()上面的模板替换为下面的模板(类似于此答案的方法 2 ),它使用以下方式提交表单将表单数据转换为查询参数后的POST方法:
<!DOCTYPE html>\n<html>\n <head>\n <meta charset="utf-8">\n <meta name="viewport" content="width=device-width, initial-scale=1">\n <script>\n document.addEventListener(\'DOMContentLoaded\', (event) => {\n document.getElementById("myForm").addEventListener("submit", function (e) {\n var myForm = document.getElementById(\'myForm\');\n var qs = new URLSearchParams(new FormData(myForm)).toString();\n myForm.action = \'/disable?\' + qs;\n });\n });\n </script>\n </head>\n <body>\n <h1>Disable a category</h1>\n <form method="post" id="myForm">\n <label for="cat_name">Enter a category name to disable:</label><br>\n <input type="text" id="cat_name" name="cat_name">\n <input class="submit" type="submit" value="Submit">\n </form>\n </body>\n</html>\nRun Code Online (Sandbox Code Playgroud)\n您仍然可以将其定义为路径参数,并在前端使用 JavaScript 来修改action的属性<form>,将表单元素的值<input>作为路径参数传递给 URL,类似于前面描述的那样。
应用程序.py
\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\'templates\')\n\n@app.post(\'/disable/{name}\')\ndef disable_cat(name: str):\n return f\'{name} category has been disabled.\'\n\n@app.get(\'/\', response_class=HTMLResponse)\ndef main(request: Request):\n return templates.TemplateResponse(\'index.html\', {\'request\': request})\nRun Code Online (Sandbox Code Playgroud)\n模板/index.html
\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset="utf-8">\n <meta name="viewport" content="width=device-width, initial-scale=1">\n <script>\n document.addEventListener(\'DOMContentLoaded\', (event) => {\n document.getElementById("myForm").addEventListener("submit", function (e) {\n var myForm = document.getElementById(\'myForm\');\n var catName = document.getElementById(\'catName\').value;\n myForm.action = \'/disable/\' + catName;\n });\n });\n </script>\n </head>\n <body>\n <h1>Disable a category</h1>\n <form method="post" id="myForm">\n <label for="catName">Enter a category name to disable:</label><br>\n <input type="text" id="catName" name="catName">\n <input class="submit" type="submit" value="Submit">\n </form>\n </body>\n</html>\nRun Code Online (Sandbox Code Playgroud)\n如果您想在点击submitHTML 按钮时阻止页面重新加载/重定向<form>,而是在同一页面中获取结果,您可以使用Fetch API(一个 JavaScript 接口/库)来发出异步 HTTP 请求,类似于这个答案,以及这个答案和这个答案。此外,人们可以调用该函数,如本答案Event.preventDefault()中所述,以防止默认操作。下面的示例基于之前的选项(即选项 3);但是,如果您希望阻止浏览器在提交时刷新页面,则下面相同的方法(即发出异步 HTTP 请求)也可以用于前面演示的选项 1 和 2 。<form>
应用程序.py
\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\'templates\')\n\n@app.post(\'/disable/{name}\')\ndef disable_cat(name: str):\n return f\'{name} category has been disabled.\'\n\n@app.get(\'/\', response_class=HTMLResponse)\ndef main(request: Request):\n return templates.TemplateResponse(\'index.html\', {\'request\': request})\nRun Code Online (Sandbox Code Playgroud)\n模板/index.html
\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset="utf-8">\n <meta name="viewport" content="width=device-width, initial-scale=1">\n <script>\n document.addEventListener(\'DOMContentLoaded\', (event) => {\n document.getElementById("myForm").addEventListener("submit", function (e) {\n e.preventDefault() // Cancel the default action\n var catName = document.getElementById(\'catName\').value;\n fetch(\'/disable/\' + catName, {\n method: \'POST\',\n })\n .then(resp => resp.text()) // or, resp.json(), etc.\n .then(data => {\n document.getElementById("response").innerHTML = data;\n })\n .catch(error => {\n console.error(error);\n });\n });\n });\n </script>\n </head>\n <body>\n <h1>Disable a category</h1>\n <form id="myForm">\n <label for="catName">Enter a category name to disable:</label><br>\n <input type="text" id="catName" name="catName">\n <input class="submit" type="submit" value="Submit">\n </form>\n <div id="response"></div>\n </body>\n</html>\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
9955 次 |
| 最近记录: |