• 六、python Django REST framework数据处理[序列化]


    一、序列化和反序列化

    序列化:序列化就是从数据库里面取出数据—>并且把数据格式改为能直接返回的格式(如json、xml)。补充:django rest引入这一步的目的就是为了简便格式的处理,这样能少写很多繁琐的代码

    反序列化:反序列化就是用户向服务器发送参数(如json)—>变为数据库可以识别的,中间还要经过数据的验证

    1.继承serializers.Serializer

    1.1 初始化配置

    过程:对应模型models.py里面的模型在serializers.py进行创建,此步为了能够让serializers识别模型

    App/models.py

    class User(models.Model):
        id = models.IntegerField(primary_key=True)
        name = models.CharField(max_length=20)
    
        def __str__(self):
            return self.name
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    App/serializers.py
    注意:此处写的语法规则与定义模型时类似但也有不同,如下面是此参数说明

    class UserSerializer(serializers.Serializer):
        id = serializers.IntegerField(label='ID')
        name = serializers.CharField(max_length=20,label='名称')
    
    • 1
    • 2
    • 3
    字段字段构造方式
    BooleanFieldBooleanField()
    NullBooleanFieldNullBooleanField()
    CharFieldCharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
    EmailFieldEmailField(max_length=None, min_length=None, allow_blank=False)
    RegexFieldRegexField(regex, max_length=None, min_length=None, allow_blank=False)
    SlugFieldSlugField(maxlength=50, min_length=None, allow_blank=False)正则字段,验证正则模式 [a-zA-Z0-9-]+
    URLFieldURLField(max_length=200, min_length=None, allow_blank=False)
    UUIDFieldUUIDField(format=‘hex_verbose’)format:① ‘hex_verbose’ 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a"② ‘hex’ 如 "5ce0e9a55ffa654bcee01238041fb31a"③’int’ - 如: "123456789012312313134124512351145145114"④’urn’ 如: “urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a”
    IPAddressFieldIPAddressField(protocol=‘both’, unpack_ipv4=False, **options)
    IntegerFieldIntegerField(max_value=None, min_value=None)
    FloatFieldFloatField(max_value=None, min_value=None)
    DecimalFieldDecimalField(max_digits, decimal_places, coerce_to_string=None,max_value=None,min_value=None)max_digits: 最多位数decimal_palces: 小数点位置
    DateTimeFieldDateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
    DateFieldDateField(format=api_settings.DATE_FORMAT, input_formats=None)
    TimeFieldTimeField(format=api_settings.TIME_FORMAT, input_formats=None)
    DurationFieldDurationField()
    ChoiceFieldChoiceField(choices)choices与Django的用法相同
    MultipleChoiceFieldMultipleChoiceField(choices)
    FileFieldFileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
    ImageFieldImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
    ListFieldListField(child=, min_length=None, max_length=None)
    DictFieldDictField(child=)
    参数名称作用
    max_length最大长度
    min_lenght最小长度
    allow_blank是否允许为空
    trim_whitespace是否截断空白字符
    max_value最小值
    min_value最大值
    read_only表明该字段仅用于序列化输出,默认False
    write_only表明该字段仅用于反序列化输入,默认False
    required表明该字段在反序列化时必须输入,默认True
    default反序列化时使用的默认值
    allow_null表明该字段是否允许传入None,默认False
    validators该字段使用的验证器
    error_messages包含错误编号与错误信息的字典
    label用于HTML展示API页面时,显示的字段名称
    help_text用于HTML展示API页面时,显示的字段帮助提示信息

    1.2 序列化

    核心:Serializer(instance=None, data=empty, **kwarg) # 给instance值就是使用序列化,给data值就是使用反序列化

    1.2.1 转换格式

    注意:如果要被序列化的是包含多条数据的查询集,添加many=True,如:serializer = UserSerializer(instance=user,many=True)

    from testWeb.models import User
    from testWeb.serializers import UserSerializer
    user= User.objects.get(id=2)
    serializer = UserSerializer(instance=user)# 进行序列化
    print(serializer.data) # 获取序列化从数据库提取出来的数据
    
    # 遇到关联的对象数据不是只有一个,而是包含多个数据,添加many=True
    serializer = UserSerializer(instance=user,many=True)# 进行序列化
    
    # 使用外键的对象,则需要用外键对应serializer.py里面的序列类
    ① 错例子
    o = Student.objects.get(id=3).foreign # Student关联Teacher
    oo = StudentSerializer(o) # 此处有问题应该为Teacher关联类
    ② 正确例子
    o = Student.objects.get(id=3).foreign # Student关联Teacher
    oo = TeacherSerializer(o) # 正确
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    外键问题
    缘由:django rest在把models模型转换为serializer序列类时,大部分属性都和model一样,但是外键这里进行单独处理

    1. 值为id
    h = serializers.PrimaryKeyRelatedField(read_only=True, many=True) 
    
    • 1
    1. 值为models.py自己设置的__str__的返回值
    h = serializers.StringRelatedField(label='图书')
    
    • 1
    1. 值关联对象的数据值
    h = BookInfoSerializer() # 此为关联对象
    
    • 1

    1.3 反序列化

    1.3.1 验证

    验证流程:

    >>> data = {"name":"5559"}
    >>> response = TeacherSerializer(data=data) 
    >>> response.is_valid()                     
    True
    >>> response.save() 
    <Teacher: 5559>
    
    # response.errors 查看报错内容
    >>> response.errors
    {'name': [ErrorDetail(string='该字段是必填项。', code='required')]}
    
    # 验证报错
    >>> response.is_valid(raise_exception=True) # 当发送错误直接报错
    Traceback (most recent call last):
      File "", line 1, in <module>
      File "C:\Users\Loser\AppData\Local\Programs\Python\Python38\lib\site-packages\rest_framework\serializers.py", line 235, in is_valid
        raise ValidationError(self.errors)
    rest_framework.exceptions.ValidationError: {'name': [ErrorDetail(string='该字段是必填项。', code='required')]}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    验证规则:

    1. validate_<自己定义的名字>

    serializers.py

    class TeacherSerializer(serializers.Serializer):
        id = serializers.IntegerField(label='ID')
        name = serializers.CharField(max_length=20,label='名称')
        def validate_name(self,value):
            if value != '853':
                raise serializers.ValidationError("853失败")
            else:
                return True # 必须要提供返回值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    >>> data ={ "name":"859"}            
    >>> o = TeacherSerializer(data=data) 
    >>> o.is_valid(raise_exception=True) 
    Traceback (most recent call last):
      File "", line 1, in <module>
      File "C:\Users\Loser\AppData\Local\Programs\Python\Python38\lib\site-packages\rest_framework\serializers.py", line 235, in is_valid
        raise ValidationError(self.errors)
    rest_framework.exceptions.ValidationError: {'name': [ErrorDetail(string='853失败', code='invalid')]}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. validate(多字段一同验证)

    serializers.py

    class TeacherSerializer(serializers.Serializer):
        id = serializers.IntegerField(label='ID')
        name = serializers.CharField(max_length=20,label='名称')
        
        def validate(self,data):
            if data['name'] != '853':
                raise serializers.ValidationError("853失败")
            else:
                return True # 必须要提供返回值
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    >>> data ={ 'name':"859"}            
    >>> o = TeacherSerializer(data=data)   
    >>> o.is_valid(raise_exception=True)
    Traceback (most recent call last):
      File "", line 1, in <module>
      File "C:\Users\Loser\AppData\Local\Programs\Python\Python38\lib\site-packages\rest_framework\serializers.py", line 235, in is_valid
        raise ValidationError(self.errors)
    rest_framework.exceptions.ValidationError: {'non_field_errors': [ErrorDetail(string='853失败', code='invalid')]}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    1.3.2 转换格式

    解释:当数据被验证后,需要自己写入create()和update()函数,当你执行save()时,其会帮你判断执行create()还是update(),ModelSerializer包含默认的create()和update()的实现

    
    	# save()函数源码
    	def save(self, **kwargs):
    		validated_data = {**self.validated_data, **kwargs}
    		if self.instance is not None:
                self.instance = self.update(self.instance, validated_data)
                assert self.instance is not None, (
                    '`update()` did not return an object instance.'
                )
            else:
                self.instance = self.create(validated_data)
                assert self.instance is not None, (
                    '`create()` did not return an object instance.'
                )
    	# create()自定义返回一个数据给save()
        def create(self, validated_data):
            """新建"""
            return Teacher(**validated_data)
            
    	# update()自定义返回一个数据给save()
        def update(self, instance, validated_data):
            """更新,instance为要更新的对象实例"""
            instance.btitle = validated_data.get('btitle', instance.btitle)
            instance.bpub_date = validated_data.get('bpub_date', instance.bpub_date)
            instance.bread = validated_data.get('bread', instance.bread)
            instance.bcomment = validated_data.get('bcomment', instance.bcomment)
            return instance
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    2.继承serializers.ModelSerializer

    介绍:与Serializer功能一致,但代码更精简(常用)

    区别:

    1. 基于模型类自动生成一系列字段
    2. 基于模型类自动为Serializer生成validators,比如unique_together
    3. 包含默认的create()和update()的实现

    2.1 初始化配置(区别)

    过程:基于模型类自动生成一系列字段

    App/models.py

    class Teacher(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=20)
    
        def __str__(self):
            return self.name
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    App/serializers.py

    class TeacherSerializer(serializers.ModelSerializer):
        """图书数据序列化器"""
        class Meta:
            model = Teacher
            fields = '__all__'
    
    • 1
    • 2
    • 3
    • 4
    • 5

    指定字段:

    1. fields:来明确字段,__all__表名包含所有字段或者写明具体哪些字段
        class Meta:
            model = Teacher
            fields = ('id', 'like', 'go')
    
    • 1
    • 2
    • 3
    1. exclude:明确排除改字段别的都要
        class Meta:
            model = Teacher
            exclude = ('image',)
    
    • 1
    • 2
    • 3
    1. extra_kwargs:添加或修改原有的选项参数
            extra_kwargs = {
                'go': {'min_value': 5, 'required': True},
                'like': {'min_value': 5, 'required': True},
            }
    
    • 1
    • 2
    • 3
    • 4
    1. 自定义添加
    class StudentSerializer(serializers.ModelSerializer):
        class Meta:
            model = Student
            fields = '__all__'
            name = serializers.CharField(max_length=20, label='名称') # 自己给其新增
            extra_kwargs={
                'passwd':{'required':False},
                'time':{'required':False}
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.2 序列化(区别)

    解释:大体类似无明显区别

    2.3 反序列化(区别)

    解释:包含默认的create()和update()的实现

    使用:

    ① save
    >>> data = {"name":"85999"}
    >>> r = TeacherSerializer(data=data) 
    >>> r.is_valid()
    True
    >>> r.save()
    <Teacher: 85999>
    ② update
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    【C语法学习】19 -关闭和刷新文件
    【Paper】2013_Attitude and Altitude Controller Design for Quad-Rotor Type MAVs
    PIMPL技巧
    Python hashlib 模块详细教程:安全哈希与数据完整性保护
    Elasticsearch学习-ES中的别名是什么
    Springboot整合WebScoket
    使用vite搭建vue3
    【云原生】五、Docker 网络管理
    RabbitMQ的基本使用
    基于Mendix移动原生的离线应用
  • 原文地址:https://blog.csdn.net/weixin_46765649/article/details/126145231