改造REST-Framework,自定义修饰器为ViewSet中每个Action指定单独的Serializer
在 REST-Framework 的 ViewSet 中,一般是通过 ViewSet 类的 serializer_class 属性来指定视图所使用的 Serializer。
但是很多时候我们需要为 ViewSet 中的某个 Action 指定不同的 Serializer。 比如在 UserViewSet中有一个修改密码的 Action:change_password,我们需要单独为它指定一个 ChangePasswordSerializer。
根据官方文档,我们可以这样做,重写 ViewSet 类的 get_serializer_class 方法,自己实现判断逻辑返回需要的 Serializer。
1 | def get_serializer_class(self): |
这样在 change_password 方法中我们就可以直接通过 self.get_serializer() 得到 ChangePasswordSerializer 对象了。
但是这不是一个优雅的解决方法,我们应该劲量避免代码中出现硬编码!!!
为了优雅的解决这个问题,我们需要实现一个方法装饰器和一个 Mixin 类。
首先是一个装饰器,用于为 Action 指定 Serializer。
1 | def action_serializer(serializer): |
接下来是一个 Mixin 类,重写 get_serializer_class 方法,返回使用了 action_serializer 装饰器修饰的 Action 的 Serializer 类即可。
1 | class ActionSerializerMixin(object): |
这样在我们的 UserViewSet 中,代码就可以简化成这样了,十分优雅。
1 |
|
其实还有一个更简单的方法
但是我暂时没有仔细看APIView类的源码,不确定在实例化ViewSet以后修改serializer_class属性会不会造成什么问题。
这个方法就是直接在装饰器中修改ViewSet对象的serializer_class属性,这样就只需要向action方法添加一个装饰器就能实现我们想要的功能了。
1 | from functools import wraps |
改造REST-Framework,自定义修饰器为ViewSet中每个Action指定单独的Serializer
https://blog.dennic365.com/2019/04/19/rest-framework-viewset-action-serializer/