DRF-序列化

序列化

序列化:由于我们在数据库中获取的数据是queryset类型,无法向前端返回json,这一部分需要自己转换,rest的序列化可以提供这个关系转化。

不使用drf序列化实现

    def get(self,request,*args,**kwargs):
        #方式一:django中queryset类型转换,不使用restframework
        roles = Role.objects.all().values('id','name')
        roles = list(roles)
        ret = json.dumps(roles,ensure_ascii=False)
        return HttpResponse(ret)

 

方式二,使用drf进行序列化

模型层

class Role(models.Model):
name = models.CharField(max_length=12)

序列化类

from rest_framework import serializers
class RoleSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField() #这个必须跟数据库的字段一致,如果设置了source=name值,就无需一一对应

视图层

对多个对象进行序列化

def get(self,request,*args,**kwargs):
roles = Role.objects.all()
seri = RoleSerializer(instance=roles,many=True) #将roles进行序列化转换,如果结果中有多条数据,需要设置many=true
print(seri.data) #序列化后的结果,是一个有序字典
ret = json.dumps(seri.data,ensure_ascii=False)
return HttpResponse(ret)

对单个对象进行序列化

    def get(self,request,*args,**kwargs):#方式三:对单个对象进行序列化转换
        roles = Role.objects.all().first()
        ser = RoleSerializer(instance=roles,many=False)        #如果结果中有多条数据,需要设置many=true
        print(ser.data)         #序列化后的结果,是一个有序字典
        ret = json.dumps(ser.data,ensure_ascii=False)
        return HttpResponse(ret)

 

 

其他序列化的写法

class UserInfoSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()
    人员类型 = serializers.CharField(source='usertype')
    gp = serializers.CharField(source='group.name')
    # roles = serializers.CharField(source='roles.all')
    roles = serializers.SerializerMethodField()     #自定义显示,需要搭配以下函数

    def get_roles(self,row):
        obj_list = row.roles.all()
        ret = []
        for item in obj_list:
            ret.append({'id':item.id,'name':item.name})
        return ret

 

常用的序列化字段

BooleanField()
NullBooleanField()
CharField()
EmailField()
RegexField()
SlugField()
URLField()
UUIDField()
IPAddressField()
IntegerField()
FloatField()
DecimalField()
DateTimeField()
DateField()
TimeField()
ChoiceField()
FileField()
ImageField()

 

特殊的序列化类

class UserInfoSerializer(serializers.ModelSerializer):
    group = serializers.HyperlinkedIdentityField(view_name='gp',lookup_url_kwarg='pk',lookup_field='group_id')  #反向解析,将group解析成url
    class Meta:
        model = UserInfoModel      #此处是model层的模型
        fields = '__all__'        #表示多所有字段序列化
        # fields = ['id','username','password']    #指定某个字段序列化
        depth = 2       #该配置表示,如果字段是外键,那么是可以点出来的,这个数字就代表可以点出几层

视图函数

class UserInfo(APIView):
    #api:http://127.0.0.1:8002/app02/v1/userinfo/
    authentication_classes=[]
    permission_classes=[]
    throttle_classes=[]
    def get(self,request,*args,**kwargs):
        userinfo = UserInfoModel.objects.all()
        ser = UserInfoSerializer(instance=userinfo,many=True,context={'request': request})  #context={'request': request}用做解析成url用
        ret = json.dumps(ser.data,ensure_ascii=False)
        return HttpResponse(ret)

 

 

 

 

 

反序列化

Serializer类还可以帮我们把前端传来的数据进行校验后反序列化,并保存到数据库中。

模型层

class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField()
#序列化类
class
BookSerializer(serializers.Serializer): # 校验前端数据时name字段长度不能超过8位 name = serializers.CharField(max_length=8) price = serializers.IntegerField() # 新增数据,validated_data是符合条件的字段数据 def create(self, validated_data): book_obj = models.Book.objects.create(**validated_data) return book_obj # 修改数据,validated_data是符合条件的字段数据 # instance是要修改数据的对象 def update(self, instance, validated_data): # 修改name字段值 instance.name = validated_data.get('name') # 修改price字段值 instance.price = validated_data.get('price') instance.save() return instance

视图类

class BookAPIView(APIView):
    
    def post(self, request):
        # 前端数据传给data参数
        ser = BookSerializer(data=request.data)
        # 校验数据是否符合规范
        if ser.is_valid():
            ser.save()
            return Response({'msg':'添加成功'})
        return Response({'msg':'添加失败'})
    
    def put(self, request, bid):
        book_obj = models.Book.objects.filter(pk=bid).first()
        ser = BookSerializer(instance=book_obj, data=request.data)
        # 校验数据是否符合规范
        if ser.is_valid():
            ser.save()
            return Response({'msg':'修改成功'})
        return Response({'msg':'修改失败'})
  • 注意:
  • 保存到数据库中用的是Serializer类中的save()方法
  • 在使用save()方法前需要先使用is_valid()校验数据
  • 添加数据,Serializer类需要自行编写create()方法
  • 修改数据,Serializer类需要自行编写update()方法
  • 执行save()方法是会判断对象中是否有instance参数,无则执行create()方法,有则执行update()方法
  • validated_data是符合条件的字段数据
  • create()方法和update()方法需要返回新增的对象和修改后的对象

常见的方法和属

save() 保存到数据库
is_valid() 校验数据是否符合规范
errors 数据校验失败的原因
validated_data 符合条件的数据(只有is_valid()为True才有数据)
data 创建对象时传的数据
instance 创建对象时传的模型层对象
posted @ 2022-11-28 23:20  powfu  阅读(89)  评论(0)    收藏  举报