zoukankan      html  css  js  c++  java
  • 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方法完成的
    
  • 相关阅读:
    bootstrap实战练习中涉及的知识点(很有用哦!)
    Markdown的最常用标记符号有哪些?
    队列的插入 和出列 阻塞 时间 问题
    ArrayBlockingQueue和LinkedBlockingQueue的使用
    自己总结 :并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和 使用场景总结
    战斗由客户端来做,后端来验证 方式 解决 一些弊端思路
    类 文件 右下角呈现 红色小圆圈,里面有一个J 标记
    苏州儿童医保
    Error: opening registry key 'SoftwareJavaSoftJava Runtime Environment' could not find java.dll
    intellj(idea) 编译项目时在warnings 页签框里 报 “xxx包不存在” 或 “找不到符号” 或 “未结束的字符串字面值” 或 “需要)” 或 “需要;”等错误提示
  • 原文地址:https://www.cnblogs.com/cnhyk/p/12467056.html
Copyright © 2011-2022 走看看