五、DRF 模型序列化器ModelSerializer

上一章:

四、DRF序列化器create方法与update方法_做测试的喵酱的博客-CSDN博客

零、前提

项目表与接口表 models.py


class Projects(models.Model):
    id = models.AutoField(primary_key=True, verbose_name='id主键', help_text='id主键')
    name = models.CharField(max_length=20, verbose_name='项目名称', help_text='项目名称',
                            unique=True)
    leader = models.CharField(max_length=10, verbose_name='项目负责人', help_text='项目负责人')

    # c.使用default指定默认值(如果指定默认值后,在创建记录时,改字段传递,会使用默认值)
    is_execute = models.BooleanField(verbose_name='是否启动项目', help_text='是否启动项目',
                                     default=True)

    # d.null=True指定前端创建数据时,可以指定该字段为null,默认为null=False,DRF进行反序列化器输入时才有效
    # e.blank=True指定前端创建数据时,可以指定该字段为空字符串,默认为blank=False,DRF进行反序列化器输入时才有效
    desc = models.TextField(verbose_name='项目描述信息', help_text='项目描述信息',
                            null=True, blank=True, default='')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')

    class Meta:
        # i.db_table指定创建的数据表名称
        db_table = 'tb_projects'
        # 为当前数据表设置中文描述信息
        verbose_name = '项目表'
        verbose_name_plural = '项目表'
        # 项目表,默认根据id进行排序
        ordering = ['id']

    def __str__(self):
        return f"项目名称:{self.name},项目负责人:{self.leader}"

class Interfaces(models.Model):
    id = models.AutoField(primary_key=True, verbose_name='id主键', help_text='id主键')
    name = models.CharField(verbose_name='接口名称', help_text='接口名称', max_length=20, unique=True)
    tester = models.CharField(verbose_name='测试人员', help_text='测试人员', max_length=10)
    # e.ForeignKey第一个参数为必传参数,指定需要关联的父表模型类
    #   方式一:直接使用父表模型类的引用
    #   方式二:可以使用'子应用名称.父表模型类名'(推荐)
    projects = models.ForeignKey('miaoschool.Projects', on_delete=models.CASCADE,
                                 verbose_name='所属项目', help_text='所属项目')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
    class Meta:
        # db_table指定创建的数据表名称
        db_table = 'tb_interfaces'
        # 为当前数据表设置中文描述信息
        verbose_name = '接口表'
        verbose_name_plural = '接口表'
        ordering = ['id']

    def __str__(self):
        return f"接口名称:{self.name}"

一、ModelSerializer 介绍

模型序列化器ModelSerializer 的作用,相比于模型类Serializer主要解决了两个问题

1、ModelSerializer 中,会自动生成 create 方法 与update方法

2、ModelSerializer 中,会自动生成模型类的所有字段,不需要手动一个一个的去写。

其他功能,与序列化器一致,包括联合校验,单字段校验。 

    定义模型序列化器类
    1、继承serializers.ModelSerializer类或者其子类
    2、需要在Meta内部类中指定model、fields、exclude类属性参数
    3、model指定模型类(需要生成序列化器的模型类)
    4、fields指定模型类中哪些字段需要自动生成序列化器字段
    5、会给id主键、指定了auto_now_add或者auto_now参数的DateTimeField字段,添加read_only=True,仅仅只进行序列化输出
    6、有设置unique=True的模型字段,会自动在validators列表中添加唯一约束校验<UniqueValidator
    7、有设置default=True的模型字段,会自动添加required=False
    8、有设置null=True的模型字段,会自动添加allow_null=True
    9、有设置blank=True的模型字段,会自动添加allow_blank=True

1.1 模型序列化器ModelSerializer 应用

在项目中,一般是用的是ModelSerializer,而不是使用serializers.Serializer

ModelSerializer 不需要一个字段一个字段的去写,而是直接通过模型类做了映射。

class ProjectModelSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Projects
        fields = "__all__"

继承serializers.ModelSerializer

内部类Meta中,model设置映射的模型类

fields= 设置,需要做映射的字段,为 "__all__" 时,表示对模型类中所有的字段做了映射。

1.2 fields= 设置映射模型类的哪些字段 

  • fields = "__all__"
  • fields = ('id', 'name', 'leader')
  • exclude = ('create_time', 'update_time')

1.2.1 fields = "__all__" 映射模型类的所有字段

模型类中,所有的字段都需要做序列化处理时。使用

fields = "__all__"

class ProjectModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Projects
        fields = "__all__"

1.2.2 fields = ('id', 'name', 'leader') 映射部分字段

模型类中,只有部分字段都需要做序列化处理时。比如序列化处理只需要处理

id 、 name 、leader 这三个字段,其他字段全都忽略。使用fields = () ,

这是一个元组,当只有一个值时,需要加一个逗号 fields = ("id ",)

class ProjectModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Projects
        fields = ('id', 'name', 'leader')

1.2.3 exclude = ('create_time', 'update_time')  不处理部分字段

在Projects模型类中,有几个字段不需要做序列化的处理,剩余其他的字段都需要做序列化处理。

我们这里可以通过exclude 指定过滤不需要做序列化处理的字段。

exclude = ('create_time', 'update_time')

class ProjectModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Projects
        exclude = ('create_time', 'update_time')

1.3 views视图调用序列化器

class ProjectsView(View):
    
    def post(self,request):
        # 1、获取json参数并转化为python中的数据类型(字典)
        try:
            dic_data = json.loads(request.body)
        except Exception as e:
            return JsonResponse({'msg': '参数有误'}, status=400)
        # 获取反序列化的实例对象
        projects_serializer_obj = ProjectModelSerializer(data=dic_data)
        # 对数据进行校验
        # 校验不通过
        if not projects_serializer_obj.is_valid():
            return JsonResponse(projects_serializer_obj.errors, status=400)

        projects_serializer_obj.save()

        # 对创建的数据进行数据回显(序列化)
        # serializer = StudentSerializer(instance=student)
        return JsonResponse(projects_serializer_obj.data, status=201)
  

二、修改自动生成的序列化器字段

2.1 重新定义一个字段,来替换系统映射的字段

使用serializers.ModelSerializer ,序列化,处理所有的字段时,是根据models定义表字段的要求进行校验的。

如models.py中 中,模型类Projects 的name字段,只要求了max_length=20 只要求了最大长度,没有要求最小长度。

class Projects(models.Model):
    id = models.AutoField(primary_key=True, verbose_name='id主键', help_text='id主键')
    name = models.CharField(max_length=20, verbose_name='项目名称', help_text='项目名称',
                            unique=True)

在序列化器中,我们想要校验name字段的最小长度。可以通过重新定义name字段实现。

class ProjectModelSerializer(serializers.ModelSerializer):
  

    name = serializers.CharField(label='项目名称', help_text='项目名称', max_length=20, min_length=5,
                                 error_messages={
                                     'min_length': '项目名称不能少于5位',
                                     'max_length': '项目名称不能超过20位'
                                 }, validators=[UniqueValidator(queryset=Projects.objects.all(), message='项目名称不能重复'),
                                                )

    class Meta:
        model = Projects
        fields = "__all__"
        

2.2 对系统自动生成的字段,进行微调

1、如果自动生成的序列化器字段,只有少量不满足要求,可以在Meta中extra_kwargs字典进行微调
 2、将需要调整的字段作为key,把具体需要修改的内容字典作为value

举例:

class ProjectModelSerializer(serializers.ModelSerializer):
   

    class Meta:
        model = Projects
        fields = "__all__"
        
        extra_kwargs = {
            'leader': {
                'label': '负责人',
                'max_length': 15,
                'min_length': 2,
            },
            'name': {
                'min_length': 5
            }
        }

2.3   批量需要设置read_only=True

可以将需要批量需要设置read_only=True参数的字段名添加到Meta中read_only_fields元组
 

 read_only_fields = ('leader', 'is_execute', 'id')

三、 序列化器主表中,显示从表数据

在主表的序列化器中,增加从表数据的字段。

字段名称为 从表模型类小写名称_set

interfaces_set = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

class ProjectModelSerializer(serializers.ModelSerializer):
    interfaces_set = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Projects

        fields = "__all__"

四、序列化器处理模型类中不存在的字段

如在Projecrs模型类中,不存在 的字段。(如token字段,在模型类中没有,但是在序列化器中需要处理这个字段)

1、在序列化器中,定义该字段

class ProjectModelSerializer(serializers.ModelSerializer):
    
    token = serializers.CharField(read_only=True)

    class Meta:
        model = Projects
        fields = "__all__"

2、views视图在调用序列化器时,传该字段的值 save(key=value)

serializer.save(token="abc")

3、在序列化器中,重写 create 函数。

提取多余字段,并将多余自动剔除

   def create(self, validated_data):
        """
        a.继承ModelSerializer之后,ModelSerializer中实现了create和update方法
        b.一般无需再次定义create和update方法
        c.如果父类提供的create和update方法不满足需要时,可以重写create和update方法,最后再调用父类的create和update方法
        :param validated_data:
        :return:
        """
        token = validated_data.pop('token')
        instance = super().create(validated_data)
        return instance

整体代码:

class ProjectModelSerializer(serializers.ModelSerializer):
    token = serializers.CharField(read_only=True)

    class Meta:
        model = Projects

        fields = "__all__"


    def create(self, validated_data):
        token = validated_data.pop('token')
        instance = super().create(validated_data)
        return instance

五、重写create update方法

a.继承ModelSerializer之后,ModelSerializer中实现了create和update方法
b.一般无需再次定义create和update方法
c.如果父类提供的create和update方法不满足需要时,可以重写create和update方法,最后再调用父类的create和update方法

  def create(self, validated_data):
        """
        a.继承ModelSerializer之后,ModelSerializer中实现了create和update方法
        b.一般无需再次定义create和update方法
        c.如果父类提供的create和update方法不满足需要时,可以重写create和update方法,最后再调用父类的create和update方法
        :param validated_data:
        :return:
        """
        validated_data.pop('myname')
        validated_data.pop('myage')
        instance = super().create(validated_data)
        instance.token = "xxxxxxx"
        return instance

                
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
DRF(Django Rest Framework)是一种用于构建Web API的强大框架,它提供了丰富的功能和工具来简API的开发过程。在使用DRF时,我们经常需要定义视图和序列以及它们之间的关系来处理不同的请求和操作。 DRF的请求处理基于视图的操作方法,它们分别对应于HTTP方法,例如GET,POST,PUT,PATCH和DELETE。这些操作方法在视图中以函数的形式定义,并且通过装饰或路由来映射到相应的URL。 序列DRF的一个核心概念,它提供了一种简单而灵活的方式,将数据对象转换为可以被序列和反序列的格式,通常是JSON或XML。序列可以定义在视图中,也可以单独定义为一个类,然后在视图中使用。 在DRF中,我们可以通过定义不同的序列类来处理不同的操作。序列类可以继承自DRF提供的Serializer类或ModelSerializer类,后者自动为我们根据模型生成序列字段。 使用序列,我们可以在视图中方便地对请求进行验证、数据转换和结果序列等操作。在视图的操作方法中,我们可以通过调用序列的不同方法来进行这些操作。 例如,我们可以使用序列的`is_valid()`方法来验证请求的数据是否有效。我们还可以使用`save()`方法来保存数据,或者使用`data`属性来获取序列后的数据。此外,我们还可以通过调用`serializer_class()`方法来获取当前视图使用的序列类。 总之,DRF的action序列提供了一种方便而强大的方式来处理API的请求和操作。通过定义视图和序列,并将它们联系起来,我们可以在开发API时更加高效和灵活。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

做测试的喵酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值