首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将RedirectResponse从帖子发送到FastAPI中的GET路由?

如何将RedirectResponse从帖子发送到FastAPI中的GET路由?
EN

Stack Overflow用户
提问于 2022-07-22 07:19:02
回答 1查看 1.1K关注 0票数 4

我想使用app.post()将数据从app.get()发送到RedirectResponse

代码语言:javascript
运行
复制
@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
代码语言:javascript
运行
复制
@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)

app.get()

  • Is
  1. 如何通过RedirectResponseurl_for()resultmsg发送到URL中,以path parameterquery parameter的形式隐藏数据?我如何做到这一点?

在尝试这种方式时,我得到了错误starlette.routing.NoMatchFound: No route exists for name "homepage" and params "result".

更新:

我尝试了以下几点:

代码语言:javascript
运行
复制
return RedirectResponse(app.url_path_for(name='homepage')
                                + '?result=' + str(trans),
                                status_code=status.HTTP_303_SEE_OTHER)

上面的方法是工作的,但它的工作方式是将param发送为query param,也就是说,localhost:8000/?result=hello看起来类似于这个localhost:8000/?result=hello。有没有办法做同样的事情,但不显示在URL中?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-23 07:23:33

对于从POST重定向到GET方法,请看一下thisthis的答案,说明如何做到这一点,以及使用status_code=status.HTTP_303_SEE_OTHER的原因(下面给出示例)。

至于获取starlette.routing.NoMatchFound错误的原因,这是因为request.url_for()接收path参数,而不是 query参数。您的msgresult参数是query参数,因此出现了错误。

解决方案是使用CustomURLProcessor,如thisthis应答中所建议的那样,允许您将path (如果需要)和query参数传递给url_for()函数并获得URL。至于将path和/或query参数隐藏在URL中,您可以使用与this answer类似的方法,使用history.pushState() (或history.replaceState())替换浏览器地址栏中的URL。

下面可以找到完整的工作示例(您可以使用自己的TemplateResponse代替HTMLResponse)。

代码语言:javascript
运行
复制
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)

更新

关于向url_for()添加查询参数,另一个解决方案是使用Starlette的starlette.datastructures.URL,它现在为include_query_params提供了一种方法。示例:

代码语言:javascript
运行
复制
from starlette.datastructures import URL

redirect_url = URL(request.url_for('event_msg')).include_query_params(msg="Succesfully created!")
return RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73076517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档