序列化组件
目录
知识点:
- Serializer(偏底层)、ModelSerializer(重点)、ListModelSerializer(辅助群改)
- 作用:视图中查询到的对象和queryset类型不能直接作为数据返回给前台,所以使用序列化组件
使用实例:
一、序列化用户表设计
编写models.py
from django.db import models
class User(models.Model):
SEX_CHOICES = [
[0, '男'],
[1, '女'],
]
name = models.CharField(max_length=64)
pwd = models.CharField(max_length=32)
phone = models.CharField(max_length=11, null=True, default=None)
sex = models.IntegerField(choices=SEX_CHOICES, default=0)
icon = models.ImageField(upload_to='icon', default='icon/default.jpg')
class Meta:
db_table = 'old_boy_user'
verbose_name = '用户'
verbose_name_plural = verbose_name
# 规范格式
def __str__(self):
return '%s' % self.name
二、序列化组件使用
- 序列化提供给前台的数据由后台决定,可以少提供
- 但是提供的数据库对应的字段,名字一定要与数据库字段相同
创建文件 serializer.py
# 序列化组件 - 为每一个model类提供一套序列化工具类
# 序列化组件的工作方式于Django froms组件非常相似
from rest_framework import serializers
class UserSerializer(serializers.Serializer):
name = serializers.CharField()
phone = serializers.CharField()
sex = serializers.IntegerField()
icon = serializers.ImageField()
编写 views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from . import models, serializers
class User(APIView):
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
try:
# 用户对象不能直接作为数据返回给前台
user_obj = models.User.objects.get(pk=pk)
# 序列化一下用户对象
user_ser_data = serializers.UserSerializer(user_obj).data
return Response({
'status': 0,
'msg': 0,
'result': user_ser_data
})
except:
return Response({
'status': 2,
'msg': '用户不存在',
})
else:
# 用户对象列表(queryset)不能直接作为数据返回给前台
user_obj_list = models.User.objects.all()
# 序列化一下用户对象列表
user_ser_data = serializers.UserSerializer(user_obj_list, many=True).data
return Response({
'status': 0,
'msg': 0,
'result': user_ser_data
})
运行结果:
三、自定义序列化属性
编辑 serializers.py
from rest_framework import serializers
from django.conf import settings
class UserSerializer(serializers.Serializer):
name = serializers.CharField()
phone = serializers.CharField()
# 自定义序列化属性
# 属性名随意,值由固定的命名规范方法提供:
# get_属性名(self, 参与序列化的model对象)
# 返回值就是自定义序列化属性的值
gender = serializers.SerializerMethodField()
def get_gender(self, obj):
return obj.get_sex_display()
icon = serializers.SerializerMethodField()
def get_icon(self, obj):
# settings.MEDIA_URL,自己配置的/media/,给后面高级序列化与视图准备的
# obj.icon不能直接作为数据返回,因为内容虽然是字符串,但是类型是ImageFieldFile类型
return '%s%s%s'% (r'http://127.0.0.1:8000', settings.MEDIA_URL, str(obj.icon))
运行结果:
四、反序列化组件使用
- 哪些字段必须反序列化
- 字段都有哪些安全校验
- 哪些字段需要额外提供校验
- 哪些字段间存在联合校验
- 反序列化字段都是用来入库的,不会出现自定义属性
编写serializers.py
from rest_framework import serializers
from django.conf import settings
class UserDeserializer(serializers.Serializer):
name = serializers.CharField()
pwd = serializers.CharField()
phone = serializers.CharField()
编写views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from . import models, serializers
class User(APIView):
# 只考虑单增
def post(self, request, *args, **kwargs):
request_data = request.data
# 数据是否合法(增加对象需要一个字典数据)
if not isinstance(request_data, dict) or request_data == {}:
return Response({
'status': 1,
'msg': '数据有误'
})
# 数据类型合法,但数据内容不一定合法,需要校验数据
book_ser = serializers.UserDeserializer(data=request_data)
if book_ser.is_valid():
# 校验通过,完成新增
book_obj = book_ser.save()
return Response({
'status': 0,
'msg': 'ok',
'result': serializers.UserDeserializer(book_obj).data
})
else:
# 校验失败
return Response({
'status': 1,
'msg': book_ser.errors,
})
return Response({
'status': 0,
'msg': 'ok'
})
总结
一、Serializer的构造方法:
Serializer(instance=None, data=empty, **kwargs)
1)、使用序列化器的时候一定要注意,序列化器声明了以后,不会自动执行,需要我们在视图中进行调用才可以。
2)、序列化器无法直接接受数据,需要我们在视图中创建序列化器对象时把使用的数据传递过来。(data,instance传参)
- 序列化:数据对象从数据库中查出,通过instance传入序列化器中,必须通过data属性才能将序列化后的数据传给前端,不能直接传序列化对象
- 反序列化:数据是通过request.data从前端获取到数据,通过data传入序列化器中进行校验,保存到数据库中
3)、开发restful api时,序列化器会帮我们把模型数据转换成字典。
4)、drf提供的视图会帮我们把字典转换成json,或者把客户端发过来的数据转换成字典。
二、序列化器的使用
序列化器的使用分两个阶段:
1、在客户端请求时:使用序列化器可以完成对数据的反序列化(就是前端往后端传递数据,反序列化之后保存数据)。
2、在服务器响应时,使用序列化器可以完成对数据的序列化(服务器取出数据,序列化之后往前端发送展示)。
序列化使用流程:
1、先查询出一个用户对象
from models import user
user = User.object.get(id=2)
2、构造序列化器对象
from user.serializers import UserSerializer
user_obj = Userserializer(user) #放入查询出的user对象
3、获取序列化对象 通过data属性可以获取序列化后的数据
user_ser = Userserializer(user).data
4、如果要被序列化的数据是包含多条数据的,需要添加many=True参数
user = models.User.objects.all()
user_ser = Userserialzier(user, many=True)
5、自定义序列化属性(重点)
serializers.SerializerMethodField()
反序列化使用流程:
数据验证:
1、使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象
2、在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False
3、验证失败,可以通过序列化对象的errors属性获取错误信息,返回字典,包含了字段和字段的错误
4、验证通过,可以通过序列化器对象的validated_data属性获取数据
保存数据:
视图中使用create()和save()方法
序列化类中必须重写create方法用户新增,重写update方法是修改
-
从源码可知save()方法内部调用的是序列化类中的create方法,所以新增必须要在序列化类中重写create方法