三、序列化器的总结(结合一、二)

model.py

from django.db import models

# Create your models here.
from utils.base_model import BaseModel


class Projects(BaseModel):
    name = models.CharField(max_length=20, verbose_name='项目名称', help_text='项目名称',
                            unique=True)
    leader = models.CharField(max_length=10, verbose_name='项目负责人', help_text='项目负责人')
    is_execute = models.BooleanField(verbose_name='是否启动项目', help_text='是否启动项目',
                                     default=True)
    desc = models.TextField(verbose_name='项目描述信息', help_text='项目描述信息',
                            null=True, blank=True, default='')

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

    def __str__(self):
        return f"Projects({self.name})"


class Interfaces(BaseModel):
    name = models.CharField(verbose_name='接口名称',help_text='接口名称',max_length=20,
                            unique=True)
    tester = models.CharField(verbose_name='测试人员', help_text='测试人员', max_length=10)
    projects = models.ForeignKey(Projects, on_delete=models.CASCADE,
                                 verbose_name='所属项目', help_text='所属项目',related_name="interfaces")

    class Meta:
        # db_table指定创建的数据表名称
        db_table = 'tb_interfaces'
        # 为当前数据表设置中文描述信息
        verbose_name = '接口表'
        verbose_name_plural = '接口表'
        ordering = ['id']

    def __str__(self):
        return f"{self.name}"

简单的定义方式

然后在serializers.py中定义序列化器,一般继承ModelSerializer,快速生成 模型的序列化器。
在这里插入图片描述

额外的定义

  1. 如果转化的序列化器不符合要求,可以使用 extra_kwargs 进行局部修改
    • 如时间进行 格式化输出
    • 修改某字段的各种校验不通过的提示语使用 error_messages
    • 还可以使用自定义方法
  2. validate_字段名() ,单字段校验
  3. validate() , 多字段联合校验

反序列化时,代码校验执行顺序为:1 >>>>2 >>>> >3

如下:
在这里插入图片描述

from rest_framework import serializers
from rest_framework.validators import UniqueValidator

from .models import Projects,Interfaces


class InterfaceModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Interfaces
        fields = "__all__"
        extra_kwargs ={
            "update_time": {
                'format' : '%Y年%m月%d日 %H:%M:%S'
            }
        }

# 自定义方法
def is_contain_keyword(value):
    if '李' not in value:
        raise serializers.ValidationError('复制人必须姓李')   # 必须是抛出这种异常


class ProjectsModelSerializer(serializers.ModelSerializer):
    # 外键字段
    # interfaces =serializers.PrimaryKeyRelatedField(many=True,read_only=True)
    # interfaces = serializers.StringRelatedField(many=True,read_only=True)                     # 会用 __str__ 返回的字符串来展示
    # interfaces = serializers.SlugRelatedField(many=True, read_only=True,slug_field="name")      # 会用指定的某个字段(需是唯一的)来 展示
    interfaces = InterfaceModelSerializer(many=True, read_only=True)

    def validate_name(self, attr: str):
        if not attr.endswith('项目'):
            raise serializers.ValidationError("项目名称中,必须以“项目 结尾")
        return attr

    def validate(self,attrs):
        attrs.get('leader')
        attrs.get('name')
        pass		# 判断每个字段长度 等等
        return attrs


    class Meta:
        model = Projects
        fields = ["id","update_time","name","leader","is_execute","interfaces"]        # '__all__'
        extra_kwargs ={
            "update_time": {'format' : '%Y年%m月%d日 %H:%M:%S'},                                                   #【局部修改】 序列化输出时: 展示时间格式
            "name":{'min_length':3,
                    'error_messages':{'max_length': '项目名称不能多余20位','min_length': '项目名称不能少于3位'}},        #【局部修改】 反序列化校验时,修改提示内容,补充定义某字段的最小长度等

            # "leader":{"validators":[UniqueValidator(queryset=Projects.objects.all(),message="领导人要唯一,(默认为:该字段必须唯一。)")]}    # 这个点在name中已经有这个了

            # validataors 中还能用自定义方法:如下      (再运行过程中,会吧leader的值传个方法,从而进行校验)
            "leader": {
                "validators": [
                    # 方法1   方法不用打括号
                    # 方法2
                    is_contain_keyword
                ]}
        }


补充

补充: 还有两个和validate 同等级的方法(项目的案例?待补充),

  • 反序列化校验时,单字段校验的入口方法
  • 序列化输出的入口方法

校验的入口方法def to_internal_value(self, data):

    def to_internal_value(self, data):
        # to_internal_value方法,它是单字段  校验的入口方法
        tmp =super().to_internal_value(data)    #  (这里就表示在执行单字段校验)
        """
         # 这里可以增加 单字段校验结束之后的数据 进行修改的代码
                print("单字段校验后, 联合字段校验前   可以做的事情")        # tmp["name"]
        """
        return tmp

输入的出口方法def to_representation

    def to_representation(self, instance):
        tmp =super(ProjectsModelSerializer, self).to_representation(instance)
        """
        # 这里可以最后改造数据再进行返回
            tmp["name"]="新名字"
        """
        tmp["name"] = "新名字"
        return tmp

补充2create方法,和update方法、
serializer.save() 时,会调用这两个方法。
模型序列化器是自动带了这两个方法,实际上也是可以进行重写的
(比如save方法传了一些参数时:要重写,参考https://blog.csdn.net/Ataoker/article/details/131176006最侯一个菜单)
源码代码思维:django 中,把模型.objects.create() 的代码放到了序列化器中,好处是:抽离出 模型 的代码,不管哪种模型,只需要 serialize.save() ,就能完成创建 或者更新
在这里插入图片描述

可修改的方法

校验时:
0、单字段校验 def validate_name()
1、校验的入口方法:def to_internal_value(self, data) (单字段校验后,组合字段校验前的事情可以在这里做)
2、多字段联合校验方法 def validate()

修改输出
4、def create() 和 update() 方法
5、def to_representation(), 可以把响应改了

可以用这个方式的笔记,后面有空改
https://note.youdao.com/s/8L4wu3Z4 + https://note.youdao.com/s/RuzZJ0Mp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值