DRF使用UpdateModelMixin更新数据遇递归错误,求正确实现方式
解决UpdateModelMixin使用时的递归错误与正确数据更新方式
首先,你遇到的「maximum recursion depth exceeded」错误原因非常明确——你的put方法里写了return self.put(self,request,*kwargs,**kwargs),这相当于无限递归调用自己,Python的递归深度有限,自然会触发这个错误。
接下来给你梳理正确的实现方式,结合你要做的「仅允许用户更新自己的产品」这个需求,我们一步步调整代码:
核心修复与优化点
1. 修复递归调用问题
因为你继承了UpdateModelMixin,这个Mixin已经帮你实现了数据更新的核心逻辑(包括序列化验证、保存数据等),你只需要在put方法里调用它提供的update()方法即可,而不是自己调用put。
2. 统一实例获取逻辑
你原来的get方法里写了获取用户自有产品的逻辑,为了避免代码重复,同时让UpdateModelMixin能正确找到要更新的实例,我们需要重写get_object方法——这是DRF视图中用来获取单个实例的标准方法,Mixin的update方法也会依赖它来获取要修改的对象。
3. 规范错误响应
把原来返回400的逻辑换成抛出Http404异常,DRF会自动将其转换为404响应,这更符合REST规范(404表示资源不存在,400用于请求参数错误的场景)。
修改后的完整代码
from rest_framework.views import APIView from rest_framework import mixins, status from rest_framework.response import Response from rest_framework.exceptions import Http404 from .models import Product from .serializers import ProductSerializer class ProductOwnserSingleViewAPIView(APIView, mixins.UpdateModelMixin): queryset = Product.objects.all() serializer_class = ProductSerializer def get_object(self): # 兼容URL路径传参和GET参数传ID的情况 product_id = self.kwargs.get('id') or self.request.GET.get('id') if not product_id: raise Http404 try: return Product.objects.get( author_id=self.request.user.id, product_id=product_id ) except Product.DoesNotExist: raise Http404 def put(self, request, *args, **kwargs): # 调用Mixin的update方法处理更新逻辑 return self.update(request, *args, **kwargs) def get(self, request, *args, **kwargs): product = self.get_object() serializer = ProductSerializer(instance=product, context={"request": request}) return Response(serializer.data)
额外说明
- 如果是RESTful风格的API,更推荐把产品ID放在URL路径中(比如
/api/products/123/),这时候你需要在URL配置中添加对应的参数,比如:# urls.py from django.urls import path from .views import ProductOwnserSingleViewAPIView urlpatterns = [ path('api/products/<int:id>/', ProductOwnserSingleViewAPIView.as_view()), ] - 当你发送PUT请求时,只需要在请求体中携带需要更新的字段数据即可(ID已经通过URL或GET参数传递,不需要在请求体里重复携带,当然如果携带了也没关系,序列化器会忽略只读字段)。
内容的提问来源于stack exchange,提问作者devmrh
相关产品推荐
相关产品推荐

