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 | 创建对象时传的模型层对象 |

浙公网安备 33010602011771号