fastapi (starlette) RedirectResponse 重定向到 post 而不是 get 方法

2023-12-05

返回 RedirectResponse 对象后,我遇到了奇怪的重定向行为

事件.py

router = APIRouter()

@router.post('/create', response_model=EventBase)
async def event_create(
        request: Request,
        user_id: str = Depends(get_current_user),
        service: EventsService = Depends(),
        form: EventForm = Depends(EventForm.as_form)
):
    event = await service.post(
       ...
   )
    redirect_url = request.url_for('get_event', **{'pk': event['id']})
    return RedirectResponse(redirect_url)


@router.get('/{pk}', response_model=EventSingle)
async def get_event(
        request: Request,
        pk: int,
        service: EventsService = Depends()
):
    ....some logic....
    return templates.TemplateResponse(
        'event.html',
        context=
        {
            ...
        }
    )

路由器.py

api_router = APIRouter()

...
api_router.include_router(events.router, prefix="/event")

这段代码返回结果

127.0.0.1:37772 - "POST /event/22 HTTP/1.1" 405 Method Not Allowed

好的,我看到由于某种原因调用了 POST 请求而不是 GET 请求。我搜索解释并发现 RedirectResponse 对象默认为代码 307 并调用 POSTlink

我遵循建议并添加状态

redirect_url = request.url_for('get_event', **{'pk': event['id']}, status_code=status.HTTP_302_FOUND)

And get

starlette.routing.NoMatchFound

为了实验,我正在改变@router.get('/{pk}', response_model=EventSingle) to @router.post('/{pk}', response_model=EventSingle)

并且重定向成功完成,但是 post 请求在这里不适合我。我究竟做错了什么?

UPD

用于运行的html表单事件/创建 logic

基本.html

<form action="{{ url_for('event_create')}}" method="POST">
...
</form>

基本视图.py

@router.get('/', response_class=HTMLResponse)
async def main_page(request: Request,
                    activity_service: ActivityService = Depends()):
    activity = await activity_service.get()
    return templates.TemplateResponse('base.html', context={'request': request,
                                                            'activities': activity})

当您想在 POST 之后重定向到 GET 时,最佳实践是重定向303状态码,所以只需将您的代码更新为:

    # ...
    return RedirectResponse(redirect_url, status_code=303)

正如你所注意到的,重定向与307保留 HTTP 方法和正文.

完全工作的示例:

from fastapi import FastAPI, APIRouter, Request
from fastapi.responses import RedirectResponse, HTMLResponse


router = APIRouter()

@router.get('/form')
def form():
    return HTMLResponse("""
    <html>
    <form action="/event/create" method="POST">
    <button>Send request</button>
    </form>
    </html>
    """)

@router.post('/create')
async def event_create(
        request: Request
):
    event = {"id": 123}
    redirect_url = request.url_for('get_event', **{'pk': event['id']})
    return RedirectResponse(redirect_url, status_code=303)


@router.get('/{pk}')
async def get_event(
        request: Request,
        pk: int,
):
    return f'<html>oi pk={pk}</html>'

app = FastAPI(title='Test API')

app.include_router(router, prefix="/event")

要运行,请安装pip install fastapi uvicorn并运行:

uvicorn --reload --host 0.0.0.0 --port 3000 example:app

然后,将浏览器指向:http://localhost:3000/event/form

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

fastapi (starlette) RedirectResponse 重定向到 post 而不是 get 方法 的相关文章

随机推荐

  • 如何通过 HTTP 从 Internet 检索文件?

    我想从 Internet 下载文件 乍一看 InternetReadFile 似乎是一个很好且简单的解决方案 事实上 好得令人难以置信 事实上 经过一番挖掘 我开始发现它实际上存在很多问题 人们在使用这段代码时抱怨各种各样的问题 出现问题的
  • 如何在打印函数中定义变量?

    我是这个领域的新手 我正在尝试解决一个问题 不太确定实际上是否可能 我想在显示器上打印一些信息以及用户的一些输入 以下工作正常 gt gt gt print Hello input tellmeyourname tellmeyourname
  • 无法找到要实例化的界面控制器类“InterfaceController”

    每次运行项目并尝试导航到另一个屏幕时 我都会收到此错误 Unable to find interface controller class HelpInterfaceController to instantiate 我正在正确使用我所知道
  • 设备向上/向下和侧向倾斜会触发方向通知

    我有一个针对 iOS7 的应用程序构建 其中 UIViewController 应该支持横向左右和纵向 纵向上下颠倒 其他 ViewController 应该仅支持横向左右方向 我已使用通知来通知方向更改并相应地刷新子视图 我还在检查 UI
  • 如何使用XSLT仅获取某些行和某些列?

    如何使用 XSLT 转换此 XML 文件
  • 从 iPhone 应用程序拨打电话 [重复]

    这个问题在这里已经有答案了 可能的重复 从我的应用程序中拨打 iPhone 电话 我想通过 iPhone 应用程序拨打给定号码 您能建议任何最好的教程来解释它或告诉我这个过程吗 你可以试试 NSURL phoneNumberURL NSUR
  • 单击展开包含详细信息和摘要标签

    我正在使用单击展开折叠使用
  • 将文件内容读入ArrayList

    在之前的项目中 我需要将文件内容读取到数组中 现在我必须做同样的事情 只是我必须将内容读入 ArrayList 我遇到的几个问题是 如何逐步浏览 ArrayList 并分别添加每个项目 如果文件包含超过 10 个输入 则必须退出 我已经尝试
  • 如何在 Java 中并行运行某些东西?

    我正在尝试打印一个范围内的所有可能的组合 例如 如果我的lowerBound是 3 我的max是 5 我想要以下组合 5 4 5 3 4 3 我已经用这个实现了helper 下面找到的函数 当然 如果我的最大值很大 则需要很多组合 这将需要
  • 需要帮助使用泰勒级数逼近Python中的正弦函数

    我对 Python 很陌生 我正在尝试使用近似正弦函数this series 我的代码如下所示 import math def sin x n sine 0 for i in range n sign 1 i sine sine x 2 0
  • 测试一个数字是否是斐波那契数

    我知道如何制作斐波那契数列 但我不知道如何测试给定的数字是否属于斐波那契数列 我想到的一种方法是生成斐波那契数列 数字到该数字并查看它是否属于该数组 但必须有另一种更简单 更快的方法 有任何想法吗 一个非常好的测试是 N 是斐波那契数当且仅
  • 如何使用命令提示符连接到 mysql 服务器:错误

    我正在使用以下命令使用命令提示符连接到数据库 mysql mysql h localhost u test ptest test 但我收到以下错误 ERROR 1064 42000 You have an error in your SQL
  • Laravel 资源中的附加数据

    我使用控制器中的 Laravel 资源 data Project limit 100 gt get return response gt json ProjectResource collection data 我喜欢将附加信息传递给 Pr
  • Android:检查活动是否被系统从服务中销毁

    我有一项服务监听来自服务器的一些事件 服务有 START STICKY 标志 当它被操作系统杀死时 该标志使他重新启动 当服务收到事件时 我有两种情况 首先 如果活动没有被终止 我需要将结果发送到本地广播接收器并更新 UI 其次 如果它被操
  • 添加表单操作[关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 当我提交时我试图再次转到index php page servers 但是当我提交表单时重定向是index php 但实际上是index php page servers 我该如何解决
  • Chrome 扩展:检测 Google 文档中的按键

    嘿 我和我的朋友们刚接触 javascript 并且遇到了一些代码问题 目前 我们正在尝试制作一个 Chrome 扩展 通过检测击键来检测用户何时以及对特定 google 文档进行了多少操作 我们当前的方法涉及创建一个 按键 事件监听器 我
  • Codeigniter SMTP 无法连接

    我正在使用 Codeigniter 3 并且我的网站上有一个简单的联系表 此联系表单在我的本地主机 XAMPP 环境中完美运行 但在我的共享 Web 托管 BT 上却不起作用 我无法弄清楚问题是什么 我一直在与他们的支持人员联系 显然 如果
  • site_url() 在 codeigniter 框架中无法正常工作

    以下代码对于 Codeigniter 框架无法正常工作 这是我的观点 a href gt Back to Main a 您应该在控制器构造方法或像这样调用视图的函数中加载 url helper this gt load gt helper
  • 在 AngularJS 中的页面之间共享数据返回空

    通常 我编写 SPA 并且通过服务在控制器之间共享数据很简单 我没有使用 SPA 格式 没有使用 ng view 并尝试在页面之间共享数据 但在加载第二个页面 以获取数据 时它是空的 第 1 页 索引 html div div
  • fastapi (starlette) RedirectResponse 重定向到 post 而不是 get 方法

    返回 RedirectResponse 对象后 我遇到了奇怪的重定向行为 事件 py router APIRouter router post create response model EventBase async def event