使用UpdateAPIView实现Django对象增改时的报错问题排查
Django PUT接口实现创建/更新用户的问题修复
问题分析
1. PUT已存在用户时id字段必填错误
请求URL中包含用户ID(pk),但序列化器校验时提示id字段必填。原因是UpdateAPIView不会自动将URL中的pk填充到序列化器的校验数据,而你的RawUserSerializer包含了id字段,且id作为模型主键默认是必填项,请求体未传入时校验失败。
2. PUT不存在用户时返回404
UpdateAPIView的get_object()方法会强制检查对象是否存在,不存在则抛出404异常,不符合你“创建或更新”(upsert)的需求。
修复方案
修改UserUpdate视图,自定义PUT逻辑实现upsert,并自动将URL中的pk传入序列化器:
from django.http import JsonResponse from rest_framework import generics, status from profiling.api.serializers import RawUserSerializer from profiling.models import RawUser class UserUpdate(generics.GenericAPIView): queryset = RawUser.objects.all() serializer_class = RawUserSerializer def put(self, request, *args, **kwargs): pk = kwargs.get('pk') # 尝试获取实例,不存在则返回None try: instance = self.get_object() except generics.Http404: instance = None # 将URL中的pk写入请求数据,避免id字段校验错误 request_data = request.data.copy() request_data['id'] = pk # 根据实例是否存在初始化序列化器 serializer = self.get_serializer(instance, data=request_data) if instance else self.get_serializer(data=request_data) serializer.is_valid(raise_exception=True) # 执行创建或更新操作 if instance: raw_user = serializer.update(instance, serializer.validated_data) response_status = status.HTTP_200_OK else: raw_user = serializer.create(serializer.validated_data) response_status = status.HTTP_201_CREATED return JsonResponse({'user_id': raw_user.id}, status=response_status)
关键修改点
- 继承
GenericAPIView而非UpdateAPIView,摆脱默认的强制存在检查逻辑 - 捕获
get_object()的404异常,实现“不存在则创建”的逻辑 - 将URL中的
pk复制到请求数据,让序列化器能获取到id字段通过校验 - 根据实例状态分别调用
update或create,返回对应HTTP状态码(更新返回200,创建返回201)
内容的提问来源于stack exchange,提问作者Nakeuh
相关产品推荐
相关产品推荐

