13 多表序列化与反序列化
Posted cnhyk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了13 多表序列化与反序列化相关的知识,希望对你有一定的参考价值。
多表序列化与反序列化
1)外键字段要参与反序列化,所以外键字段设置为write_only
2)外键关系需要连表序列化结果给前台,可以用@property来自定义连表序列化
连表序列化用自定义@property完成:内部实现可以自定义逻辑,也可以走序列化类
外键字段留给反序列化来使用
案例
urls.py
url(r'^books/$', views.BookAPIView.as_view()),
url(r'^books/(?P<pk>d+)/$', views.BookAPIView.as_view()),
models.py
class Book(BaseModel):
# ...
@property # @property字段默认就是read_only,且不允许修改
def publish_name(self):
return self.publish.name
@property # 自定义序列化过程
def author_list(self):
temp_author_list = []
for author in self.authors.all():
author_dic = {
"name": author.name
}
try:
author_dic['phone'] = author.detail.phone
except:
author_dic['phone'] = ''
temp_author_list.append(author_dic)
return temp_author_list
@property # 借助序列化类完成序列化过程
def read_author_list(self):
from .serializers import AuthorModelSerializer
return AuthorModelSerializer(self.authors.all(), many=True).data
serializers.py
# 辅助序列化类
class AuthorDetailModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.AuthorDetail
fields = ['phone']
# 辅助序列化类
class AuthorModelSerializer(serializers.ModelSerializer):
detail = AuthorDetailModelSerializer(many=False, read_only=True)
class Meta:
model = models.Author
fields = ['name', 'detail']
# 主序列化类
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = ('name', 'price', 'image', 'publish', 'authors', 'publish_name', 'author_list', 'read_author_list')
extra_kwargs = {
'image': {
'read_only': True,
},
'publish': { # 系统原有的外键字段,要留给反序列化过程使用,序列化外键内容,用@property自定义
'write_only': True,
},
'authors': {
'write_only': True,
}
}
views.py
# 六个必备接口:单查、群查、单增、单删、单整体改(了解)、单局部改
# 四个额外接口:群增、群删、群整体改、群局部改
class BookAPIView(APIView):
# 单查群查
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
obj = models.Book.objects.filter(is_delete=False, pk=pk).first()
serializer = serializers.BookModelSerializer(instance=obj)
return APIResponse(result=serializer.data)
else:
queryset = models.Book.objects.filter(is_delete=False).all()
serializer = serializers.BookModelSerializer(instance=queryset, many=True)
return APIResponse(results=serializer.data)
# 单增群增
def post(self, request, *args, **kwargs):
# 如何区别单增群增:request.data是{}还是[]
if not isinstance(request.data, list):
# 单增
serializer = serializers.BookModelSerializer(data=request.data)
serializer.is_valid(raise_exception=True) # 如果校验失败,会直接抛异常,返回给前台
obj = serializer.save()
# 为什么要将新增的对象重新序列化给前台:序列化与反序列化数据不对等
return APIResponse(result=serializers.BookModelSerializer(obj).data, http_status=201)
else:
# 群增
serializer = serializers.BookModelSerializer(data=request.data, many=True)
serializer.is_valid(raise_exception=True) # 如果校验失败,会直接抛异常,返回给前台
objs = serializer.save()
# 为什么要将新增的对象重新序列化给前台:序列化与反序列化数据不对等
return APIResponse(result=serializers.BookModelSerializer(objs, many=True).data, http_status=201)
# 友情注释:群增其实是借助了ListSerializer来的create方法完成的
以上是关于13 多表序列化与反序列化的主要内容,如果未能解决你的问题,请参考以下文章