反序列化器

参数校验基本使用

使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据,或保存成模型类对象。

  1. 序列化器的创建: 通过data传入字典数据

     Serializer(instance=None, data=empty, **kwarg)
    
  2. 通过is_valid方法校验参数合法性

    • is_valid()方法
      • 校验参数是否合法,校验通过返回True,否则返回False
      • 传递参数:is_valid(raise_exception=True)
        • 验证失败时会抛出异常serializers.ValidationError
        • 响应时对应的状态码:400
    • errors属性: 获取校验出错信息,字典类型。
    • validated_data属性: 校验通过得到的对象,类型为OrderedDict
  3. 案例

    案例一:验证出错

     my_dict = {'create_date':'2018'}
     serializer = DepartmentSerializer(data=my_dict)
     serializer.is_valid()      # 验证不通过
     # False
     serializer.errors
     # {'create_date': [ErrorDetail(string='Date has wrong format. 
     #   Use one of these formats instead: YYYY[-MM[-DD]].', code='invalid')], 
     # 'name': [ErrorDetail(string='This field is required.', code='required')]}
    

    案例二:验证通过

 

     my_dict = {'name':'研发部33', 'create_date':'2018-1-1'}
     serializer = DepartmentSerializer(data=my_dict)
     serializer.is_valid()  # 验证通过
     # True

     serializer.validated_data
     # OrderedDict([('name', '研发部33'), 
     #     ('create_date', datetime.date(2018, 1, 1))]

参数校验的几种方式

如果默认的字段类型和选项不能满足需求,需要再补充校验行为,可以使用以下三种方法:

  • 通过字段中的validators 选项进行校验
  • validate_<field_name>方法:对<field_name>字段进行验证
  • validate方法:对多个字段进行比较校验

一、通过 validators选项校验

  • 在序列化器字段中添加validators选项参数进行校验,例如:
def validate_name(value):
    # 校验部门名称
    if not re.match('^[\u4e00-\u9fa5]+$', value):
        raise ValidationError('部门名称只能为中文')
    return value

class DepartmentSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True, label='ID')

    name = serializers.CharField(max_length=20, label='部门名称',
                                 required=True, allow_null=True, validators=[validate_name])
...

二、validate_<field>:对<field_name>字段进行验证

  • 注意:若校验失败,则 raise ValidationError异常
class DepartmentSerializer(serializers.Serializer):
    """部门数据序列化器"""
    ...
    def validate_name(self, value):
        # 校验部门名称
        if not re.match('^[\u4e00-\u9fa5]+$', value):
            raise ValidationError('部门名称只能为中文')
        return value

测试

>>> from users.models import *
>>> from users.serializers import *
>>> s = DepartmentSerializer(data={'name':'研-发部22', 'create_date':'2018-1-1'})
>>> s.is_valid()
False
>>> s.errors
{'name': [ErrorDetail(string='部门名称只能为中文或英文字母', code='invalid')]}

三、validate:同时对多个字段进行比较验证

  1. 用户注册,校验两次输入的密码是否一致

    # 模型: users/models.py
    class User(models.Model):
       name = models.CharField(verbose_name="用户名", max_length=20)
       password = models.CharField(verbose_name="密码", max_length=20)
    
    # 序列化器: users/serializer.py
    class UserSerializer(serializers.Serializer):
       name = serializers.CharField(max_length=20)
       password = serializers.CharField(max_length=20)
       password2 = serializers.CharField(max_length=20, write_only=True)
    
       # 新增用户时客户端传递请求参数:
       # {"name":"Jack",  "password": "123456", "password2":"123456"}
       def validate(self, attrs):
           # 校验两次输入的密码是否正确
           password = attrs['password']
           password2 = attrs['password2']
           if password != password2:
               raise serializers.ValidationError('两次输入的密码不一样')
           return attrs
    
  2. 测试

     >>> from users.models import *
     >>> from users.serializers import *
     >>> s = UserSerializer(data={"name":"Jack", "password":"123456", "password2":"12345"})
     >>> s.is_valid()
     False
     >>> s = UserSerializer(data={"name":"Jack", "password":"123456", "password2":"123456"})
     >>> s.is_valid()
     True

保存或修改数据

  1. Serializer类的三个方法

    • save()方法: 保存数据
    • create()方法: 新增数据
    • update()方法: 修改数据
  2. 新增或修改数据

     Serializer(instance=None, data=empty)
    
    1. 新增:创建序列化器时,没有传递了instance参数

       my_dict = {'name': '研发部xx', 'create_date': '2018-1-1'}
       s = DepartmentSerializer(data=my_dict)    
       s.save()        # 新增
      
    2. 修改:创建序列化器时,传递了instance参数

       department = Department.objects.get(id=1)
       my_dict = {'name': '研发部xx', 'create_date': '2018-1-1'}
       s = DepartmentSerializer(instance=department, data=my_dict)    
       s.save()        # 修改
      
    3. 部分修改:partial=True 参数

      1. 当修改数据时,序列化器默认要求传递所有required=True的字段,否则is_valid验证不通过
      2. 可以通过设置partial=True允许只修改部分字段,如下:

        s = DepartmentSerializer(department, data={'create_date': '2017-1-1'}, partial=True)
        
  3. 案例:重写 Serializer 类的 create() 和 update()方法

 class DepartmentSerializer(serializers.Serializer):
     """部门序列化器"""
     ...
     def create(self, validated_data):
         """保存部门"""
         return Department.objects.create(**validated_data)

     def update(self, instance, validated_data):
         """修改部门:instance为要修改的部门对象,
            validated_data为用户发请求提交过来的数据,已经通过校验
         """
         instance.name = validated_data.get('name', instance.name)
         instance.create_date = validated_data.get('create_date', instance.create_date)
         instance.save()   # 修改数据库数据
         return instance

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值