传递外键参数时触发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
相关产品推荐
相关产品推荐

