zoukankan      html  css  js  c++  java
  • restframework 序列化和反序列化外键

    前言

    • 这是博主第一次接触学习restframework框架,很多知识点零散不系统,在这不建议将此文作为指导方向。
    • 在此文讲解前,不会说明安装和配置信息,大家可以百度如何安装restframework,并自行安装成功就行。
    • 在此会讲解几种序列化和反序列化的方法,表的设计是一对多结构。

    代码实现

    序列化

    首先我们在models下新建两个模型类

    class User(SoftDeleteMode):
        GENDER_CHOICES = (
            ('1', '普通会员'),
            ('2', 'VIP会员')
        )
        name = models.CharField(max_length=100, verbose_name='昵称')
        phone = models.CharField(max_length=11, verbose_name='手机号', unique=True)
        password = models.CharField(max_length=255, verbose_name='密码')
        level = models.CharField(max_length=20, choices=GENDER_CHOICES, verbose_name='用户身份')
    
        class Meta:
            db_table = 'user'
            verbose_name = '用户表'
            app_label = 'polls' # 标记是属于哪个app的models,该属性常用于models的分层
            ordering = ['-id']  # 根据id倒序排列
    
        # 调用时返回自身的属性,不然都是显示xx object
        def __str__(self):
            return self.name
    
    
    class BookInfo(SoftDeleteMode):
        title = models.CharField(max_length=20, verbose_name='名称')
        read = models.IntegerField(default=0, verbose_name='阅读量')
        comment = models.IntegerField(default=0, verbose_name='评论量')
        author = models.ForeignKey(User, on_delete=models.CASCADE, error_messages={"does_not_exist": "作者不存在"}) # 外键
    
        class Meta:
            db_table = 'tb_books'  # 指明数据库表名
            verbose_name = '图书'  # 在admin站点中显示的名字
            app_label = 'polls'  # app_lable的值为APP的名称,这样就可以将models定义到多个文件中了。
    
        def __str__(self):
            """定义每个数据对象的显示信息"""
            return self.title
    

    每个模型定义一个serializers.ModelSerializer

    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ['id', 'name', 'phone', 'level']
    
    
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model = BookInfo
            fields = ['id', 'title', 'read', 'comment','author']
    

    通过postman请求我们的接口可以看到,author作为外键序列化后,返回的是User里的id。(忽略字段_create_time和_update_time)

    如果我们想要返回具体外键里的值,应该怎么看呢。

    • 第一种方法: 在Meta中定义一个深度depth=1
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model = BookInfo
            # 取出所有的字段
            fields = ['id', 'title', 'read', 'comment','author']
            depth = 1
    
    • 实现效果,可以看到会把外键相关的表数据序列化出来,而且是不可控的把表数据字段读了出来。但我们可能并不需要那么多的数据,包括用户密码等字段。

    • 第二种方法: 我们定义一个get_author()方法
    class BookSerializer(serializers.ModelSerializer):
        author = serializers.SerializerMethodField() 
    
        class Meta:
            .....
            
        
        # 在BookSerializer中我们定义一个方法,获取外键对应的数据
        def get_author(self, obj):
            authors_query_set = obj.author  # 拿到所有作者信息 (obj是User对象)
            return [{"id": authors_query_set.id, "name": authors_query_set.name}]
    
    
    • 实现效果: 可以看到,按照我们定义的方法返回了值,需要什么数据可以在get_author中添加即可,想要反序列化{"author": 1}作为外键添加时,不得有depth=1

    反序列化

    可以在serializers.ModelSerializer中定义与author字段相同的属性,并实例化serializers.PrimaryKeyRelatedField对象

    class BookSerializer(serializers.ModelSerializer):
        # 必须要传的参数,queryset查询集,这里我们的主表是User表,所以定义了User的查询集
        # error_messages: 错误提示信息,如果对象未找到对应的key:does_not_exist
        author = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), error_messages={"does_not_exist": "作者不存在"})
        
        class Meta:
            model = BookInfo
            fields = ['id', 'title', 'read', 'comment']
        
        def get_author(self, obj):
            authors_query_set = obj.author  # 拿到所有作者信息
            return [{"id": authors_query_set.id, "name": authors_query_set.name}]
        
    

    实现效果:

    • 添加成功

    • 添加失败

  • 相关阅读:
    PHP学习—Cookie&Session
    IP组播综合实验
    k8s kubeadm部署高可用集群
    python调用zbbix的api实现批量添加域名监控脚本
    Python调用Harbor api删除私有仓库harbor镜像
    Kubernetes故障排查指南-分析容器退出状态码
    blackbox_exporter+grafana+prometheus监控主机存活,端口存活及网站状态
    k8s中使用ceph-csi在ceph中进行数据持久化
    Jenkins+K8S流水线自动化部署Java程序
    生产环境k8s中使用helm部署prometheus+grafana监控k8s集群中相关node和pod
  • 原文地址:https://www.cnblogs.com/se7enjean/p/13186675.html
Copyright © 2011-2022 走看看