DRF中ModelViewSet的serializer_action_class动态切换不生效问题
问题原因
DRF 视图集的 self.action 存储的是当前触发的视图函数名称,而非 HTTP 请求方法名。你调用自定义的 add_remove_students 接口时,self.action 的值为 add_remove_students,你配置的字典用 put 作为键自然无法匹配,所以会走到异常分支返回默认序列化器。
解决方案
有两种可选方案,按需选择即可:
方案1:按动作名称匹配(推荐)
直接将 serializer_action_classes 的键修改为对应自定义动作的函数名,默认内置动作也可以用对应动作名匹配:
- 列表查询:
list - 详情查询:
retrieve - 新增:
create - 全量更新:
update - 部分更新:
partial_update - 删除:
destroy
修正后的代码示例:
class ClassView(viewsets.ModelViewSet): queryset = Class.objects.all() serializer_class = ClassSerializer serializer_action_classes = { # 键修改为自定义动作的函数名 'add_remove_students': AddStudentstoClassSerializer, # 也可以同时配置内置动作的序列化器 'update': OtherUpdateSerializer, } def get_serializer_class(self): """ 根据当前动作返回对应的序列化器类 """ try: return self.serializer_action_classes[self.action] except (KeyError, AttributeError): print("iam ClassSerializer") return super().get_serializer_class()
方案2:按HTTP请求方法匹配
如果你确实需要所有PUT请求都使用同一个序列化器,可以修改匹配逻辑,取请求方法作为匹配键:
def get_serializer_class(self): """ 根据HTTP请求方法返回对应的序列化器类 """ try: # 转为小写和你配置的键格式匹配 return self.serializer_action_classes[self.request.method.lower()] except (KeyError, AttributeError): print("iam ClassSerializer") return super().get_serializer_class()
内容的提问来源于stack exchange,提问作者Reactoo
相关产品推荐
相关产品推荐

