03.03 DjangoRestFrameWork中针对数据读写使用不同的序列化处理

我们在使用DjangoRestFrameWork的过程中可能需要对不同的请求GET/POST/PUT/DELETE,使用不同的序列化器。在GET序列化器包含许多嵌套数据,比如外键,但是在POST更新数据的时候不一定需要这些数据。

我们使用不同的序列化器进行读取和更新操作有两种方式

  • 在每个视图类上重写getserializerclass函数,根据不同的请求方法来确定要返回哪个序列化器。如果我们需要在多个视图类中进行这些操作,我们就要编写一个mixin类来实现这些工作!
  • 添加mixin类,在视图类中集成
    mixin是一个python类,其中包含自定义属性和方法。它本身不是很有用,但是当它继承到一个类中时,该类可以访问mixin的特殊属性和方法。具体实现如下:
<code>class ReadWriteSerializerMixin:
read_serializer_class = None
write_serializer_class = None

def get_serializer_class(self):
if self.action in ['create', 'update', 'partial_update', 'destory']:
return self.get_write_serializer_class()

def get_write_serializer_class(self):
assert self.write_serializer_class is not None, ("'%s' should either include a `write_serializer_class` attribute, or override the `get_write_serializer_class` method." % self.__class__.__name__)
return self.write_serializer_class

def get_read_serializer_class(self):
assert self.read_serializer_class is not None, ("'%s' should either include a `read_serializer_class` attribute, or override the `get_read_serializer_class` method." % self.__class__.__name__)
return self.read_serializer_class/<code>

增加两个属性,readserializerclass和writeserializerclass。每个属性都有一种相应的方法来捕获使用Mixin的错误,默认未设置这些属性。如果你的视图类未设置对应的属性或者重写对应的方法,则get*serializer_class方法将引发AssertionError异常。

getserializerclass方法对要使用的序列化器做出最终决定。对于API的“更新”操作,它返回writeserializerclass; 否则返回readserializerclass。

mixin在视图类中这样使用:

<code>from rest_framework.viewsets import ModelViewSet
from .mixins import ReadWriteSerializerMixin
from .models import MyModel
from .serializers import ModelReadSerializer, ModelWriteSerializer

class MyModelViewSet(ReadWriteSerialzerMixin, ModelViewSet):
queryset = MyModel.objects.all()
read_serializer_class = ModelReadSerializer
write_serializer_class = ModelWriteSerializer/<code>

视图类MyModelViewSet可以从ReadWriteSerializerMixin中访问属性和方法。这意味着当调用MyModelViewSet的API时,将自动调用ReadWriteSerializerMixin中的getserializerclass方法,并根据发出的API请求的类型决定要使用的序列化器。如果我们需要对返回的序列化器做出更精细的处理(加入我们想对列表请求使用更有限的序列化器,而在检索请求中使用更多的序列化器),那么我们的视图类可以重写getwriteserializer_class方法以处理该逻辑。


(此处已添加圈子卡片,请到今日头条客户端查看)


分享到:


相關文章: