我想使用从 发送数据app.post()到。app.get()RedirectResponse
@app.get('/', response_class=HTMLResponse, name='homepage')
async def get_main_data(request: Request,
msg: Optional[str] = None,
result: Optional[str] = None):
if msg:
response = templates.TemplateResponse('home.html', {'request': request, 'msg': msg})
elif result:
response = templates.TemplateResponse('home.html', {'request': request, 'result': result})
else:
response = templates.TemplateResponse('home.html', {'request': request})
return response
Run Code Online (Sandbox Code Playgroud)
@app.post('/', response_model=FormData, name='homepage_post')
async def post_main_data(request: Request,
file: FormData = Depends(FormData.as_form)):
if condition:
......
......
return RedirectResponse(request.url_for('homepage', **{'result': str(trans)}), status_code=status.HTTP_302_FOUND)
return RedirectResponse(request.url_for('homepage', **{'msg': str(err)}), status_code=status.HTTP_302_FOUND)
Run Code Online (Sandbox Code Playgroud)
result或msg通过RedirectResponse,url_for()至app.get()?path parameter或query parameter?我该如何实现这一目标?starlette.routing.NoMatchFound: No route exists for name "homepage" and params "result".我在尝试这种方法时遇到错误。
更新:
我尝试了以下方法:
return RedirectResponse(app.url_path_for(name='homepage')
+ '?result=' + str(trans),
status_code=status.HTTP_303_SEE_OTHER)
Run Code Online (Sandbox Code Playgroud)
上面的代码可以工作,但它是通过将参数作为query参数发送来工作的,即 URL 看起来像这样localhost:8000/?result=hello。有没有办法做同样的事情但不显示在 URL 中?
对于从方法重定向POST到GET方法,请查看此和此答案,了解如何执行此操作以及使用原因status_code=status.HTTP_303_SEE_OTHER(示例如下)。
至于报错的原因starlette.routing.NoMatchFound,这是因为request.url_for()接收path参数,而不是 query参数。你的msg和result参数是query一个;因此,出现错误。
解决方案是使用 a CustomURLProcessor,如本答案和本答案中所建议的那样,允许您将path(如果需要)和query参数传递给url_for()函数并获取 URL。至于隐藏URL 中的path和/或参数,您可以使用与此答案类似的方法,即使用(或) 替换浏览器地址栏中的 URL。queryhistory.pushState()history.replaceState()
完整的工作示例可以在下面找到(您可以使用自己的示例TemplateResponse代替HTMLResponse)。
from fastapi import FastAPI, Request, status
from fastapi.responses import RedirectResponse, HTMLResponse
from typing import Optional
import urllib
app = FastAPI()
class CustomURLProcessor:
def __init__(self):
self.path = ""
self.request = None
def url_for(self, request: Request, name: str, **params: str):
self.path = request.url_for(name, **params)
self.request = request
return self
def include_query_params(self, **params: str):
parsed = list(urllib.parse.urlparse(self.path))
parsed[4] = urllib.parse.urlencode(params)
return urllib.parse.urlunparse(parsed)
@app.get('/', response_class=HTMLResponse)
def event_msg(request: Request, msg: Optional[str] = None):
if msg:
html_content = """
<html>
<head>
<script>
window.history.pushState('', '', "/");
</script>
</head>
<body>
<h1>""" + msg + """</h1>
</body>
</html>
"""
return HTMLResponse(content=html_content, status_code=200)
else:
html_content = """
<html>
<body>
<h1>Create an event</h1>
<form method="POST" action="/">
<input type="submit" value="Create Event">
</form>
</body>
</html>
"""
return HTMLResponse(content=html_content, status_code=200)
@app.post('/')
def event_create(request: Request):
redirect_url = CustomURLProcessor().url_for(request, 'event_msg').include_query_params(msg="Succesfully created!")
return RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER)
Run Code Online (Sandbox Code Playgroud)
关于向url_for()函数添加查询参数,另一个解决方案是使用 Starlette 的starlette.datastructures.URL,它现在提供了一种include_query_params. 例子:
from starlette.datastructures import URL
redirect_url = URL(request.url_for('event_msg')).include_query_params(msg="Succesfully created!")
Run Code Online (Sandbox Code Playgroud)
该request.url_for()函数现在返回一个starlette.datastructures.URL对象。因此,您可以按如下方式添加查询参数:
redirect_url = request.url_for('event_msg').include_query_params(msg="Succesfully created!")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10459 次 |
| 最近记录: |