Django中DRF框架序列化器类中关联字段及反序列化校验

一、自定义序列化器类

# 1、自定义的序列化器类实际上也是Field的子类
# 2、所以自定义的序列化器类可以作为另一个序列化器中的字段来使用
class InterfaceSerilizer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField()
    tester = serializers.CharField()


class ProjectSerilizer(serializers.Serializer):

    leader = serializers.CharField(label='项目负责人', help_text='项目负责人', default='阿名')
    is_execute = serializers.BooleanField()
    interfaces_set = InterfaceSerilizer(label='所属接口信息', help_text='所属接口信息', read_only=True,many=True)

二、序列化器类中进行校验

1.自定义的校验规则:

# 1、可以在序列化器字段上使用validators指定自定义的校验规则
# 2、validators必须得为序列类型(列表),在列表中可以添加多个校验规则
# 3、DRF框架自带UniqueValidator校验器,必须得使用queryset指定查询集对象,用于对该字段进行校验
# 4、UniqueValidator校验器,可以使用message指定自定义报错信息
# 5、校验规则的执行顺序?
#   对字段类型进行校验 -> 依次验证validators列表中的校验规则 -> 从右到左依次验证其他规则 -> 调用单字段校验方法
#   -> 调用多字段联合校验方法validate方法

2.自定义的校验函数:

# 1、可以在类外自定义校验函数
# 2、第一个参数为待校验的值
# 3、如果校验不通过,必须得抛出serializers.ValidationError('报错信息')异常,同时可以指定具体的报错信息
# 4、需要将校验函数名放置到validators列表中
def is_contains_keyword(value):
    if '项目' not in value:
        raise serializers.ValidationError('项目名称中必须得包含“项目”关键字')


class ProjectSerilizer(serializers.Serializer):
    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='项目名称不能重复'),
                                                is_contains_keyword])
    leader = serializers.CharField(label='项目负责人', help_text='项目负责人', default='阿名')
    is_execute = serializers.BooleanField()

3、序列化器类中DateTimeField类型值处理:

# a.DateTimeField可以使用format参数指定格式化字符串
# b.可以任意序列化器字段上使用error_messages来自定义错误提示信息
# c.使用校验选项名(校验方法名)作为key,把具体的错误提示信息作为value
class ProjectSerilizer(serializers.Serializer):

    leader = serializers.CharField(label='项目负责人', help_text='项目负责人', default='阿名')
    is_execute = serializers.BooleanField()

    update_time = serializers.DateTimeField(label='更新时间', help_text='更新时间', format='%Y年%m月%d日 %H:%M:%S',
                                            error_messages={'required': '该字段为必传参数'})
三、序列化器中关联字段处理

# 1、可以定义PrimaryKeyRelatedField来获取关联表的外键值
# 2、如果通过父获取从表数据,默认需要使用从表模型类名小写_set作为序列化器类中的关联字段名称
# 3、如果在定义模型类的外键字段时,指定了realated_name参数,那么会把realated_name参数名作为序列化器类中的关联字段名称
# 4、PrimaryKeyRelatedField字段,要么指定read_only=True,要么指定queryset参数,否则会报错
# 5、如果指定了read_only=True,那么该字段仅序列化输出
# 6、如果指定了queryset参数(关联表的查询集对象),用于对参数进行校验
# 7、如果关联字段有多个值,那么必须添加many=True,一般父表获取从表数据时,关联字段需要指定
# interfaces_set = serializers.PrimaryKeyRelatedField(label='项目所属接口id', help_text='项目所属接口id', many=True, queryset=Interfaces.objects.all(), write_only=True)

# 1、使用StringRelatedField字段,将关联字段模型类中的__str__方法的返回值作为该字段的值
# 2、StringRelatedField字段默认添加了read_only=True,该字段仅序列化输出
# interfaces_set = serializers.StringRelatedField(many=True)

# 1、使用SlugRelatedField字段,将关联模型类中的某个字段,作为该字段的值
# 2、如果指定了read_only=True,那么该字段仅序列化输出
# 3、如果该字段需要进行反序列化输入,那么必须得指定queryset参数,同时关联字段必须有唯一约束
# interfaces_set = serializers.SlugRelatedField(slug_field='name', many=True, queryset=Interfaces.objects.all())

# interfaces_set = InterfaceSerilizer(label='所属接口信息', help_text='所属接口信息', read_only=True, many=True)

四、序列化器类中对单个字段及多个字段的联合校验

1、单个字段的校验

# 1、可在序列化器类中对单个字段进行校验
# 2、单字段的校验方法名称,必须把validate_作为前缀,加上待校验的字段名,如:validate_待校验的字段名
# 3、如果校验不通过,必须得返回serializers.ValidationError('具体报错信息')异常
# 4、如果校验通过,往往需要将校验之后的值,返回
# 5、如果该字段在定义时添加的校验规则不通过,那么是不会调用单字段的校验方法
   def validate_name(self, attr: str):
        if not attr.endswith('项目'):
            raise serializers.ValidationError('项目名称必须得以“项目”结尾')
        return attr

2.多个字段的联合校验

# 1、可以在序列化器类中对多个字段进行联合校验
# 2、使用固定的validate方法,会接收上面校验通过之后的字典数据
# 3、当所有字段定义时添加的校验规则都通过,且每个字段的单字段校验方法通过的情况下,才会调用validate
    def validate(self, attrs: dict):
        if len(attrs.get('leader')) <= 4 or not attrs.get('is_execute'):
            raise serializers.ValidationError('项目负责人名称长度不能少于4位或者is_execute参数为False')
        return attrs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值