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

Django SimpleJWT移除request.body引用触发RawPostDataException异常

问题原因解析

这个报错的核心是Django/DRF的请求体数据流只能被读取一次:

  • 调用token_view(request._request)时,TokenObtainPairView内部会通过访问request.data解析请求体,这会把请求体的数据流读取到末尾。
  • 后续再访问request.data时,尝试再次读取已耗尽的数据流就会抛出RawPostDataException。
  • 提前执行body = request.body的作用是让DRF把请求体内容缓存到内存中,后续访问request.data时会直接使用缓存内容,不会重复读取数据流,因此不会报错。
规范优化实现

直接调用视图函数的方式不符合DRF设计规范,更合理的做法是继承TokenObtainPairView扩展功能,从根源避免数据流冲突,同时贴合DRF视图扩展逻辑:

from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from django.contrib.auth.models import User

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        # 调用父类逻辑生成基础token数据
        data = super().validate(attrs)
        
        # 添加自定义的用户权限信息
        user = self.user
        data.update({
            "user_access": {
                "is_staff": user.is_staff,
                "is_admin": user.is_superuser
            }
        })
        # 调整key名称与原代码一致
        data["access_token"] = data.pop("access")
        data["refresh_token"] = data.pop("refresh")
        
        return data

class CustomSignInView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer

然后在urls.py中替换原有视图:

from django.urls import path
from .views import CustomSignInView

urlpatterns = [
    path('auth/signin/', CustomSignInView.as_view(), name='signin'),
]
优化优势
  • 完全遵循DRF扩展机制,代码更易维护和迭代
  • 避免直接操作底层request._request对象,消除潜在兼容性风险
  • 无需额外缓存请求体的冗余操作,彻底解决数据流读取冲突问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:05:06