发出 PUT 请求后重定向:我可以使用 GET 请求重定向吗?

问题描述 投票:0回答:1

对于我的 Django 项目,我有一个主要模型 Book 和一个关联的 BookViewSet(来自 Django REST Framework)。从前端,可以编辑其他对象,例如 Page,它 POST 到相应的 PageViewSet。

Page 对象的更改也会影响 Book,因此我想在处理 Page 的更改后返回更新的 BookViewSet。

通过 PageViewSet 处理页面的 PUT 请求后,我尝试利用

redirect
快捷方式将请求发送到 BookViewSet,如下所示:

return redirect('/books/10', pk=book_id)

我期望(并希望)这会发出 GET 请求,以便后端使用“检索”方法通过 BookViewSet 返回更新的书籍。

但是,BookViewSet 似乎仍然收到 PUT 请求,这意味着该请求将被发送到 BookViewSet 的“update”方法。

  1. 这是预期的吗?

  2. 如果是这样,有没有办法在更改页面后“获取”更新的图书视图?我可以通过将该逻辑放入 BookViewSet 的“更新”方法中来实现此目的,但我已经在“检索”方法中拥有该逻辑并且不想重复它。

我最近发现这种模式被描述为“发布、重定向、获取”,并且不确定是否还有其他方法可以实现该 GET 请求。

页面视图集

本例的具体操作是对页面的“布局”进行更新:

class PageViewSet(LoginRequiredMixin, viewsets.ModelViewSet):
    queryset = Page.objects.all()
    renderer_classes = [TemplateHTMLRenderer, JSONRenderer]
    serializer_class = PageSerializer

    def update(self, request, pk=None):
        page = self.get_object()
        page.update_layout(
            Layout.objects.get(
                id=request.data[f"{page.id}-layout"]
            )  # Form field prefix is set to page ID
        )

        return redirect("book-detail", pk=page.book.id)

GET 请求后控制台显示以下内容:

(django.request) log/log_response: Bad Request: /books/11/
[15/Oct/2024 13:14:40] "PUT /books/11/ HTTP/1.1" 400 15
django http django-rest-framework
1个回答
0
投票

是的,这是预期的行为

修复它在某种程度上取决于您如何使用后端。

Django 的

redirect()
默认为
HTTP 302
,如果您查看链接,这意味着符合 HTTP 规范的客户端将不会更改其 HTTP 方法(意味着
PUT
被保留)。这就是您所看到的行为。

如果您使用的是您可以控制的前端,那么无论是针对该特定页面还是作为中间件,编写一个特殊情况对于您来说都是微不足道的,只要您遵循,您就可以将其强制更改为

GET
302
s.

但是您的帖子也表明您正在使用浏览器或其他人的客户端以及他们的默认行为。如果是这样的话,也许它符合规范?如果是,将后端的响应更改为

HTTP 303
可能会解决该问题,因为
303
是专门针对您在本文中描述的场景而设计的。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections

Django 的

redirect()
没有任何会发出
HTTP 303
的内置类。

您可以 try

status=303
作为参数传递,但我不确定这是否有效。

如果这不起作用,我的下一个建议是使用

DRF
s 本地人手工制作适当的重定向:

url = reverse("book-detail", pk=page.book.id)

return Response(
    status  = status.HTTP_303, 
    headers = {
        'Location': url
    }
)
© www.soinside.com 2019 - 2024. All rights reserved.