DRF-django_restframework序列化与校验

104 阅读3分钟

save的返回值

class USserializer(serializers.ModelSerializer):
    #自定义字段list.dict
    tags = serializers.ListField()
    # mytag = serializers.DictField()

    class Meta:
        model = models.UserInfo
        #可验证是否在数据库存在
        fields = ['name','gender','depart','tags',]
class Useradd(APIView):
    def post(self,request,*args,**kwargs):
		instance = ser.save()		#返回的是UserInfo这个对象
       	return Response('123')

校验之后发返回检验的数据

class DpSerializer(serializers.ModelSerializer):
    #用于校验
    class Meta:
        model = models.Depart
        fields = '__all__'

class Dp2Serializer(serializers.ModelSerializer):
    #用于序列化
    class Meta:
        model = models.Depart
        fields = ['title','order','count']


class dpView(APIView):
    def post(self,request,*args,**kwargs):
        #校验
        ser = DpSerializer(data=request.data)
        if ser.is_valid():
            instance = ser.save()
            print(instance)
            #序列化传入数据并返回
            ser_instance = Dp2Serializer(instance = instance)
            return Response(ser_instance.data)

        else:
            return Response(ser.errors)

如果传入的字段和要保存在数据库的字段一样的话可以使用同一个序列化器进行校验和序列化

class DpSerializer(serializers.ModelSerializer):
    #用于校验
    class Meta:
        model = models.Depart
        fields = '__all__'
        
class dpView(APIView):
    def post(self,request,*args,**kwargs):
        #校验
        ser = DpSerializer(data=request.data)
        if ser.is_valid():
            instance = ser.save()
            print(instance)
            #序列化传入数据并返回
            ser_instance = DpSerializer(instance = instance)
            return Response(ser_instance.data)
        else:
            return Response(ser.errors)

如果想在同一个序列化器完成校验和序列化

要给字段传入参数

v1 = serializers.CharField(read_only=True,write_only=True)
'''
read_only   -->只有在序列化时才使用
write_only  -->只有在校验时才使用
'''

post请求体中没有传入id:

class DpSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Depart
        fields = ['id','title','order','count']
        extra_kwargs = {
            "id":{'read_only':True},
            "count":{'write_only':True}
        }

屏幕截图 2024-02-11 163842.png

针对显示choices的内容:

方法一:使用自定义字段 + read_only

class Uusializer(serializers.ModelSerializer):
    gender_info = serializers.CharField(source='get_gender_display',read_only=True)
    class Meta:
        model = models.UserInfo
        #可验证是否在数据库存在
        fields = ['name','gender','depart','gender_info']


class Uusradd(APIView):
    def post(self,request,*args,**kwargs):
        ser = Uusializer(data=request.data)
        if ser.is_valid():
            # print('US视图',ser.data)        在save前不能使用ser.data,会进入只读模式
            #要使用
            # print(ser.validated_data)
            # ser.validated_data.pop('mytag')
            ser.save()
            instance = ser.save()
            return Response(Uusializer(instance=instance).data)
        else:
            print('Us',ser.errors)
            return Response('error')

屏幕截图 2024-02-11 165421.png

方法二:使用SerializerMethodField

SerializerMethodField

这是一个只读字段。它通过调用附加到的序列化程序类上的方法来获取其值。它可用于将任何类型的数据添加到对象的序列化表示中。 签名:SerializerMethodField(method_name=None) method_name - 要调用的序列化程序上方法的名称。如果不包含此默认值get_<field_name>。 method_name参数引用的序列化方法应该接受一个参数(除了self),它是被序列化的对象。它应该返回您想要包含在对象的序列化表示中的任何内容。

原文链接:blog.csdn.net/weixin_4464…

class Uusializer(serializers.ModelSerializer):
    gender_info = serializers.CharField(source='get_gender_display',read_only=True)
    #SerializerMethodField
    gender_data = serializers.SerializerMethodField()
    class Meta:
        model = models.UserInfo
        #可验证是否在数据库存在
        fields = ['name','gender','depart','gender_info','gender_data']
        extra_kwargs = {
            "gender":{'write_only':True},
        }
        
    #定义返回数据
    def get_gender_data(self, obj):
        return {'id':obj.id,'data':obj.get_gender_display()}
class Uusradd(APIView):
    def post(self,request,*args,**kwargs):
        ser = Uusializer(data=request.data)
        if ser.is_valid():
            ser.save()
            instance = ser.save()
            return Response(Uusializer(instance=instance).data)
        else:
            print('Us',ser.errors)
            return Response('error')

屏幕截图 2024-02-11 170945.png

针对外键

方法一:类似于针对choices的方法一

class Uusializer(serializers.ModelSerializer):
        depart_info = serializers.CharField(source='depart.title',read_only=True)
        ...

方法二:嵌套


class us2dp(serializers.ModelSerializer):
    class Meta:
        model = models.Depart
        fields = '__all__'
        
class Uusializer(serializers.ModelSerializer):
    gender_info = serializers.CharField(source='get_gender_display',read_only=True)
    gender_data = serializers.SerializerMethodField()
	
    ########嵌套########
    depart_info =  us2dp(read_only=True,source='depart')
    # depart_info = serializers.CharField(source='depart.title',read_only=True)
    class Meta:
        model = models.UserInfo
        #可验证是否在数据库存在
        fields = ['name','gender','depart','depart_info','gender_info','gender_data']
        extra_kwargs = {
            "gender":{'write_only':True},
        }

屏幕截图 2024-02-11 172658.png

假如序列化和校验合并在一个序列化器,response可以直接使用ser.data

class Uusradd(APIView):
    def post(self,request,*args,**kwargs):
        ser = Uusializer(data=request.data)
        if ser.is_valid():

            ser.save()
            
           	#序列化和校验分开的情况
            # instance = ser.save()
            #return Response(Uusializer(instance=instance).data)
            
            #只使用一个序列化器
            return Response(ser.data)