Django REST Framework如何实现仅允许更新Photo的单个description字段
问题修复方案
你的整体实现思路没有问题,仅存在代码实现细节错误。
错误根源
你遇到的序列化报错有两个直接原因:
- 编写
partial_update逻辑时,初始化序列化器没有传入需要更新的Photo实例,仅传了data参数,此时序列化器的save()方法会执行创建逻辑而非更新逻辑,也不符合你修改已有照片描述的需求 - 直接将
save()返回的Photo模型实例传入Response,DRF无法直接序列化模型实例为JSON格式,因此触发类型错误
直接修复代码
修正partial_update方法即可解决报错:
def partial_update(self, request, pk=None): # 先获取要更新的Photo实例 photo = self.get_object() # 初始化序列化器时必须传入要更新的实例,只传data会触发创建逻辑 serializer = UpdateDescriptionSerializer(instance=photo, data=request.data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() # 返回序列化后的合法数据 return Response(data=serializer.data, status=status.HTTP_202_ACCEPTED)
优化方案(可选)
更符合DRF规范的写法是重写get_serializer_class方法,根据请求动作动态返回对应序列化器,直接复用UpdateModelMixin自带的partial_update逻辑,无需手动重写更新方法:
class PhotoViewSet(mixins.RetrieveModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet): """ PhotoViewSet Handle upload (create) and delete of photos. """ queryset = Photo.objects.all() serializer_class = PhotoModelSerializer def get_serializer_class(self): # 局部更新时仅用修改描述的序列化器 if self.action == 'partial_update': return UpdateDescriptionSerializer return super().get_serializer_class() def perfom_create(self, serializer): """ Upload a new photo. """ serializer.save() def perform_destroy(self, instance): """ Delete a photo. """ return super().perform_destroy(instance) def retrieve(self, request, *args, **kwargs): """ Retrieve photo information. """ response = super(PhotoViewSet, self).retrieve(request, *args, **kwargs) data = { 'photo': response.data, } response.data = data return response
内容的提问来源于stack exchange,提问作者Risker
相关产品推荐
相关产品推荐

