DRF-ModelViewSet 根据条件选择序列化
再用django写后台时候,restframework省去了很多事情,在这里记录一下如何根据不同的请求来获取不同的序列化,留给自己以后使用。
查看DRF ModelViewSet的源码,在GenericAPIView中写了获取序列化的方法。
class GenericAPIView(views.APIView):
# ...
def get_serializer_class(self):
"""
Return the class to use for the serializer.
Defaults to using `self.serializer_class`.
You may want to override this if you need to provide different
serializations depending on the incoming request.
(Eg. admins get full serialization, others get basic serialization)
"""
assert self.serializer_class is not None, (
"'%s' should either include a `serializer_class` attribute, "
"or override the `get_serializer_class()` method."
% self.__class__.__name__
)
return self.serializer_class
# ...
通过注解我们可以看出你可以重载这个函数,如果你的请求需要依赖不同的序列化。
class ViewSetMixin(object):
# ...
def initialize_request(self, request, *args, **kwargs):
"""
Set the `.action` attribute on the view,
depending on the request method.
"""
request = super(ViewSetMixin, self).initialize_request(request, *args, **kwargs)
method = request.method.lower()
if method == 'options':
# This is a special case as we always provide handling for the
# options method in the base `View` class.
# Unlike the other explicitly defined actions, 'metadata' is implicit.
self.action = 'metadata'
else:
self.action = self.action_map.get(method)
return request
和DRF中请求对应起来,看到这段代码,在这里取self.action 可以得到create、retrieve、list 等字段
可以根据不同的需要来实现不同的序列化。
我的实现方法是做了一个字典来对应,重载函数如下:
serializer_class = Example_SERIALIZERS_DICT = {
'list': ExampleListSerializer,
'create': ExampleCreateSerializer,
'update': ExampleUpdateSerializer,
'retrieve': ExampleListSerializer,
'partial_update': ExampleUpdateSerializer
}
def get_serializer_class(self):
try:
return self.serializer_class[self.action]
except KeyError:
raise Err # 处理不可对应的情况
初学这个,如果大家有更好的方案,欢迎留言,如有错误,欢迎大家指正。