• 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方法完成的
    
  • 相关阅读:
    BZOJ 4503: 两个串 FFT
    [FJOI2014]最短路径树问题
    [JSOI2009]游戏Game
    bzoj 2463 [中山市选2009]谁能赢呢?
    [CQOI2007]余数求和
    [NOI2011]兔兔与蛋蛋游戏
    [HNOI2015]实验比较
    bzoj2125 最短路
    [COGS 2877]老m凯的疑惑
    [HNOI2015]开店
  • 原文地址:https://www.cnblogs.com/cnhyk/p/12467056.html
Copyright © 2020-2023  润新知