DRF-序列化对象-0-序列化类中参数和方法【字段、钩子函数、update和create、序列化嵌套】

drf序列化类:

  • Serializer: 没有关联模型类,需要重写update和create方法
  • ModelSerializer:关联模型类,内部已经写好update和create方法,可以不用重写

Serializer序列化器的书写

class AuthorSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField(max_length=10)
    phone = serializers.CharField(max_length=11,min_length=11)
    address = serializers.CharField(max_length=200)
    
    def validate_字段名(self,value):
        #对该字段进行进一步的校验
        
        #对于钩子函数,勾出什么,就需要return什么
        return value
    
    def validate(self,attrs):
        #拿到多个字段数据,进行校验
        #校验的逻辑
        return attrs
    
    def update(self,instance,validated_data):
        #更新的逻辑
        return instance
    	#返回值自己决定,当view调用了ser.save()方法后,会调用该update方法,之后的ser.data()拿到的就是update的返回值
    
    def create(self,validated_data):
        #创建的逻辑
        return 自己定义的返回值
    	#返回值自己决定,当view调用了ser.save()方法后,会调用该create方法,之后的ser.data()拿到的就是create的返回值
    

ModelSerializer序列化器书写

class AuthorModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Author
        fields = ['id','name','phone','address']
        extra_kwargs={
            'id':{'read_only':True},
            'name':{
                'max_length':10,
                'min_length':3,
                'error_messages':{
                    'max_length':"名字长度不能大于10",
                    'min_length':"名字长度不能小于3"
                }
            },
            'phone':{
                'max_length':11,
                'min_length':11
            }
        }
    def validate_字段名(self,value):
        pass
    def validate(self,attrs):
        pass
    #对于create和update方法,在ModelSerializer中已经实现了,可以不重写

1、字段

#常用
max_length          字符串最大长度
min_length			字符串最小长度
max_value  			数值最大值
min_value 			数值最小值
default				字段反序列化时,如果没有传入数据,就使用默认值
error_messages		指定字段中,某个校验字段不通过时,输入的错误提示信息
read_only 			该字段仅用于序列化输出,默认False
write_only   		该字段仅用于反序列化输入,默认False
required			字段反序列化时必须输入数据,默认是True

#不常用
all_blank			是否允许为空,默认False
allow_null			是否传入None,默认False
label				用于html展示API页面时,显示的字段名称
help_text			用于html展示API页面时,展示的字段帮助提示信息
validators  		指明该字段使用的验证器


#source字段的功能
1、重命名:user_name = serialziers.CharField(source='name')
2、跨表查询:teacher_name = serializers.CharField(source='teacher.name')
3、choice拿值:sex = serializers.Charfield(source='get_sex_display')
	模型类中书写:sex = models.IntegerField(choice=((1,'男'),(0,'女')),default=0)
    通过source='get_字段_display',拿到choice中对应的数据

2、钩子函数

钩子函数作用:字段校验,只能做一些最基本的校验。要进一步的校验,需要通过在钩子函数写校验流程。

有局部钩子和全局钩子:

  • 局部钩子:校验的是某个字段,如:手机号码校验 (def validate_字段名(self,value))
  • 全局钩子:需同时校验多个字段,如:设置密码,需要校验两次密码是否一致 (def validate(self,attrs) )

局部钩子例子:

def validate_phone(self,value):
        print(value)
        if re.findall('^1[3456789]\d{9}$', value):
            return value
        raise ValidationError('手机格式有问题,请检查!!')

全局钩子例子:

 def validate(self,attrs):
        new_pwd = attrs.get('password')
        resure_pwd = attrs.get("resure_password")
        if new_pwd == resure_pwd:
            return attrs
        raise ValidationError("两次输入的密码不一致!!")

3、create和update方法

def create(self,validated_data):
    try:
         author = models.Auhtor.objects.create(**validated_data)
         return author
     except Exception as e:
          raise ValidationError(str(e))

def update(self,instance,validated_data):
	try:
		for key,value in validated_data.items():
            instance.key=value
        instance.save()
        return Validated_data
    except Exception as e:
        raise ValidationError(str(e))

4、序列化器嵌套

4.1、通过字段 :PrimaryKeyRelatedField :获取到关联字段的主键值

class StudentModelSerializer(serializers.ModelSerialzier):
    classmate_id = serializers.PrimaryKeyRelatedField(label='班级id',read_only=True)
    #拿到的是学生所在班级的id
    class Meta:
        model = models.Student
        fields = ['id','name','number','classmate_id']

4.2、通过字段:StringRelatedField,拿到模型类的__str方法的返回值

StringRelatedField拿到的就是模型类的__str__方法
#在模型类中,设置__str__方法
def __str__(self):
	//返回值是由自己决定的,只能返回字符串,不然会报错
	reutrn self.name
class StudentModelSerializer(serializers.ModelSerializer):
    classmate_dic = serializers.StringRelatedField(label='班级信息')
    class Meta:
        model = models.Student
        fields = ['id','name','number','classmate_dic']

4.3、通过字段接收关联的序列化对象

class ClassMate(serializers.ModelSerializer):
    class Meta:
        model = models.ClassMate
        fields = ['id','number']
        
        
class Student(serializers.ModelSerializer):
    classmate = ClassMate()
    class Meta:
        model = models.Student
        fields = ['id','name','number','classmate']

上面的当前模型类是属于多的一方,外键存在的一方。拿到的关联对象只有一个数据。

4.4、如果当前模型类是属于一的一份,拿到的关联对象是有多个数据。

  • 此时,只需要加参数 many=True

     classmate_id = serializers.PrimaryKeyRelatedField(label='班级id',read_only=True,many=True)
    
     classmate_dic = serializers.StringRelatedField(label='班级信息',many=True)
    
     classmate = ClassMate(many=True)
    

5、视图使用时,序列化器的流程

1、处理get请求时,是进行序列化操作,不会走字段校验和钩子函数。

2、post请求时,新建数据,先走字段校验、再走钩子函数、最后执行create方法
	ser.is_valid() 这个是在进行字段校验、钩子校验
	ser.save() 这是在走create方法(如果实例化对象传递进来的参数只有data时)
	此时的ser.data 拿到的是create方法的返回值
	
3、put/patch请求时,更新数据,先走字段校验、再走钩子函数,最后执行update方法
	ser.is_valid() 这个是在进行字段校验和钩子校验
	ser.save()这个是在走update方法,(实例化对象传递进来的参数有instance和data时)
	此时的ser.data拿到的是update方法的返回值
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值