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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 19:12:50