You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework如何以POST请求重定向到其他ViewSet

问题根因

默认的redirect和HttpResponseTemporaryRedirect返回的都是302状态码,主流浏览器收到302响应后会自动将后续重定向请求改为GET方法、丢弃原请求体,所以才会出现POST接口报405、request.data为空的问题。


解决方法

方案1:307状态码重定向(适配客户端跳转场景)

307状态码的规范明确要求重定向时不得修改原请求方法,且必须完整传递请求体,可以完美解决请求方法被篡改、参数丢失的问题,代码示例如下:

from django.http import HttpResponse
import json
from django.urls import reverse

class GoogleViewSet(APIView):
    permission_classes = (permissions.AllowAny,)

    def post(self, request):
        password = User.objects.make_random_password()
        # 构造307重定向响应
        response = HttpResponse(
            json.dumps({'email': 'test@test.com', 'username': 'test', 'password': password}),
            status=307,
            content_type="application/json"
        )
        # 配置重定向目标地址
        response['Location'] = reverse('v1_users:user_create')
        return response

注意:该方案依赖请求客户端支持307状态码,目前所有主流浏览器、HTTP客户端都已兼容,仅极老版本的客户端可能存在适配问题。


方案2:服务端内部直接调用逻辑(更推荐,无兼容问题)

如果不需要经过客户端跳转,完全可以在服务端内部直接调用UserViewSet的创建逻辑,性能更高、没有兼容风险,代码示例如下:

from rest_framework.request import Request
from rest_framework.parsers import JSONParser

class GoogleViewSet(APIView):
    permission_classes = (permissions.AllowAny,)

    def post(self, request):
        password = User.objects.make_random_password()
        user_data = {'email': 'test@test.com', 'username': 'test', 'password': password}
        # 构造适配UserViewSet的请求对象
        new_request = Request(
            request=request._request,
            parsers=[JSONParser()],
            authenticators=request.authenticators
        )
        new_request._full_data = user_data
        # 直接调用UserViewSet的create方法返回响应
        return UserViewSet().create(new_request)

优化建议:如果UserViewSet的create方法有权限、限流等不需要在谷歌登陆场景触发的校验,可以把用户创建的核心逻辑抽为独立公共函数,两个接口分别调用即可,逻辑更解耦。


内容的提问来源于stack exchange,提问作者Headmaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 21:48:00