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

传递外键参数时触发Django DRF「此字段为必填项」错误排查

Django JWT任务创建中username必填错误的解决方案

你在通过Swagger发送POST请求创建任务时,尽管已从JWT Token中获取到用户,仍收到如下错误:

{
  "username": [
    "This field is required."
  ]
}

核心原因是TaskSerializer要求传入username字段,但你并未将从Token获取的用户传递给序列化器,且当前代码中构造的req_data并未实际使用。以下是两种可行的解决方法:


方案1:标记username为只读字段,保存时传入用户实例

1. 调整TaskSerializer

将username设为只读字段,避免序列化器要求前端传入该参数:

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tasks
        fields = ['taskname', 'completion', 'username']
        read_only_fields = ['username']  # 添加此行,标记username为只读

2. 修改TaskView的post方法

在调用serializer.save()时,直接传入从Token获取的用户实例:

def post(self, request):
    token = request.COOKIES.get('jwt')
    if not token:
        raise AuthenticationFailed('Unauthenticated!')

    try:
        payload = jwt.decode(token, 'secret', algorithms=['HS256'])
    except jwt.ExpiredSignatureError:
        raise AuthenticationFailed('Unauthenticated!')
    
    # 获取当前用户实例
    user = User.objects.filter(username=payload['username']).first()
    if not user:
        raise AuthenticationFailed('User not found!')
    
    serializer = TaskSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    # 保存时传入username参数,关联当前用户
    serializer.save(username=user)
    return Response(serializer.data)

方案2:构造完整请求数据,传入用户ID

如果你不想修改序列化器的只读配置,可以将构造好的包含用户ID的req_data传给序列化器:

def post(self, request):
    token = request.COOKIES.get('jwt')
    if not token:
        raise AuthenticationFailed('Unauthenticated!')

    try:
        payload = jwt.decode(token, 'secret', algorithms=['HS256'])
    except jwt.ExpiredSignatureError:
        raise AuthenticationFailed('Unauthenticated!')
    
    user = User.objects.filter(username=payload['username']).first()
    if not user:
        raise AuthenticationFailed('User not found!')
    
    req_data = {
        "username": user.id,  # 外键字段需传入用户ID而非实例
        "taskname": request.data['taskname'],
        "completion": request.data['completion'],
    }
    
    serializer = TaskSerializer(data=req_data)
    serializer.is_valid(raise_exception=True)
    serializer.save()
    return Response(serializer.data)

同步更新Swagger文档

确保swagger_auto_schema的请求体定义与实际接口一致,不包含username字段:

@swagger_auto_schema(
    request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        properties={
            'taskname': openapi.Schema(type=openapi.TYPE_STRING, description='Add taskname'),
            'completion': openapi.Schema(type=openapi.TYPE_BOOLEAN, description='completion'),
        },
        required=['taskname']  # 标记必填字段
    )
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 13:35:28