Django DRF重写ModelViewSet.create调用update时AssertionError报错求助
解决Django REST Framework中ModelViewSet.create()调用update()时的AssertionError问题
这个错误的核心原因很明确:update()方法是为处理带pk的详情路由设计的,而你的create()方法对应的是列表路由(URL里没有pk参数)。哪怕你手动给kwargs加了pk,DRF的视图在初始化阶段已经检查了URL中的关键字参数,所以还是会抛出这个断言错误。
你不想重复get_serializer()的逻辑是完全合理的,下面是最规范的解决方案,既能复用现有逻辑,又能解决参数问题:
直接使用序列化器的更新流程,绕开super().update()
既然你已经找到了要更新的实例,直接用序列化器处理更新逻辑就好,完美复用你重写的get_serializer()代码:
from rest_framework.response import Response class EventViewSet(LoggingMixin, viewsets.ModelViewSet): """this is our main api. It allows an event to be created, retrieved, updated and deleted """ def create(self, request, *args, **kwargs): # 构建过滤条件,查找未关闭的对应事件 filters = Q(customer = request.data["Customer"]) & \ ~Q(status = "CLOSED") & \ Q(device_name = request.data["DisplayName"]) & \ Q(ip_address = request.data["Address"]) query_set = Event.objects.filter(filters) if query_set.exists(): # 获取要更新的实例 event_instance = query_set.first() # 用get_serializer初始化序列化器,传入实例和请求数据 # partial=False表示需要完整数据,允许部分更新可设为True serializer = self.get_serializer(event_instance, data=request.data, partial=False) # 验证数据,出错时直接抛出异常 serializer.is_valid(raise_exception=True) # 执行更新(perform_update会调用serializer.save(),也可直接调用serializer.save()) self.perform_update(serializer) # 返回更新后的序列化数据 return Response(serializer.data) else: # 没有找到未关闭的事件,调用父类的create方法创建新实例 return super().create(request, *args, **kwargs)
为什么这个方法可行?
- 完全复用了你重写的
get_serializer()逻辑,不用重复处理JSON payload的代码 - 绕开了
update()方法对URL中pk参数的依赖,因为我们手动传入了要更新的实例 - 遵循DRF的序列化器工作流程,代码更规范、可维护
为什么之前的尝试会有问题?
- 直接调用
Event.objects.update():跳过了序列化器的验证、字段处理等逻辑,导致重写的get_serializer()逻辑无法复用,还可能出现数据不一致 - 调用
update_or_create():你的过滤条件是“未关闭的事件”,而update_or_create()通常针对唯一标识字段(比如唯一约束)判断创建还是更新,和业务逻辑不匹配;且即便用了它,调用super().update()依然会遇到pk参数问题
内容的提问来源于stack exchange,提问作者pastoreerrante
相关产品推荐
相关产品推荐

