Django- REST framework(七)
一、反序列化
-
数据校验
-
在定义序列化器时,通过validators选项添加校验器
-
唯一性约束:UniqueValidator(queryset,message),参数queryset指定查询集,参数message指定校验失败返回的提示信息
class ProjectsSerializer(serializers.Serializer): """ 创建项目序列化器类 """ #1、label相当于verbose_name,help_text #2、需要输出哪些字段,那么在序列化器中就定义哪些字段 #3、read_only=True指定该字段只能序列化输出 id = serializers.IntegerField(label='ID', read_only=True) name = serializers.CharField(label='项目名称', max_length=200, help_text='项目名称', write_only=True, validators=[UniqueValidator(queryset=Projects.objects.all(), message='不是唯一')]) leader = serializers.CharField(label='负责人', max_length=50, help_text='负责人') tester = serializers.CharField(label='测试人员', max_length=50, help_text='测试人员') programer = serializers.CharField(label='开发人员', max_length=50, help_text='开发人员') pubish_app = serializers.CharField(label='发布应用', max_length=100, help_text='发布应用') #allow_null相当于模型类中的null,allow_blank相当于模型类中的blank desc = serializers.CharField(label='简要描述', help_text='简要描述', allow_blank=True, default='', allow_null=True)
-
-
自定义校验器
-
#创建自定义校验器 def is_unique_project_name(name): if '项目' not in name: raise serializers.ValidationError(detail='项目名称中必须包含"项目')
class ProjectsSerializer(serializers.Serializer): """ 创建项目序列化器类 """ #1、label相当于verbose_name,help_text #2、需要输出哪些字段,那么在序列化器中就定义哪些字段 #3、read_only=True指定该字段只能序列化输出 id = serializers.IntegerField(label='ID', read_only=True) name = serializers.CharField(label='项目名称', max_length=200, help_text='项目名称', write_only=True, validators=[UniqueValidator(queryset=Projects.objects.all(), message='不是唯一'), is_unique_project_name])
-
-
单字段校验(validate_字段名)
-
def validate_name(self, value): if value.endwith('项目'): raise serializers.ValidationError('项目名称必须以"项目"结尾') return value
在序列化定义器类的内部定义的方法,序列化器会自动识别此方法校验字段。
当校验成功后一定要返回value
-
-
多字段联合校验
-
#多字段联合校验 def validate(self, attrs): if 'icon' not in attrs['tester'] or 'icon' not in attrs['leader']: raise serializers.ValidationError('icon至少是项目负责人或项目测试人员') return attrs
-
校验顺序:
字段定义时的限制(包含validators列表条目从左到右进行校验) -> 单字段的校验(validate_字段名)->多字段联合校验
二、序列化器-Serializer类
Serializer类自带create,update方法,为对象创建及数据更新提供了直接的方法,那么在views.py中对象创建及数据更新可以进一步优化
- create
如果在创建序列化器对象时,只给data传参,那么调用save()方法,实际调用的是序列化器的create()方法
projects/serializer.py,序列化器类:
def create(self, validated_data): return Projects.objects.create(**validated_data)
优化projects/views.py中创建对象:
def post(self, request): """新增项目""" #1、从前端获取json格式数据,转化为python中的类型(反序列化) json_data = request.body.decode('utf-8') python_data = json.loads(json_data, encoding='utf-8') serializer = ProjectsSerializer(data=python_data) #调用序列化对象的is_valid方法,开始校验前端数据 #校验成功则返回True,否则返回False #raise_exception=True,那么校验失败会抛出异常 try: serializer.is_valid(raise_exception=True) except Exception as e: return JsonResponse(serializer.errors) #当调用is_valid方法之后才可以调用errors属性,获取校验的错误提示 # 校验成功之后的数据,可以使用validated_data来获取 #3、向数据库新增项目 # project = Projects.objects.create(**serializer.validated_data) #1、如果在创建序列化器对象时,只给data传参,那么调用save()方法,实际调用的是序列化器的create()方法 serializer.save() return JsonResponse(serializer.data, status=201)
- update
如果在创建序列化器对象时,只给data传参,那么调用save()方法,实际调用的是序列化器的create()方法
projects/serializer.py,序列化器类:
def update(self, instance, validated_data): instance.name = validated_data['name'] instance.leader = validated_data['leader'] instance.tester = validated_data['tester'] instance.programer = validated_data['programer'] instance.pubish_app = validated_data['pubish_app'] instance.desc = validated_data['desc'] instance.save() return instance
优化projects/views.py中更新数据库:
def put(self, request, pk): project = self.get_object(pk) #反序列化 json_data = request.body.decode('utf-8') python_data = json.loads(json_data, encoding='utf-8') serializer = ProjectsSerializer(instance=project, data=python_data) try: serializer.is_valid(raise_exception=True) except Exception as e: return JsonResponse(serializer.errors) # #4、更新项目 # project.name = python_data['name'] # project.leader = python_data['leader'] # project.tester = python_data['tester'] # project.programer = python_data['programer'] # project.pubish_app = python_data['pubish_app'] # project.desc = python_data['desc'] # project.save() #在创建序列化器对象时,如果同时给instance和data传参,那么调用save()方法时,实际调用的是序列化器的update()方法 serializer.save() #5、将模型类对象转换成python中的类型 return JsonResponse(serializer.data, status=201)
三、ModelSerializer
- 简化序列化器定义
- 功能
- 基于模型类自动生成一系列字段
- 基于模型类自动为Serializer生成validators
- 包含默认的create()和update()的实现
class ProjectsModelSerializer(ModelSerializer): #单字段的校验参照ProjectsSerializer中的定义,不能再Meta子类中定义 class Meta: #1、指定参考哪一个模型类来创建 model = Projects #2、指定模型类的那些字段来生成序列化器 #字段生成的方法: fields = "__all__"#全字段 fields = ("id", "name", "leader", "tester", "programer")#指定字段 exclude = ("pubish_app", "desc")#指定字段,生成的字段是元组内除外的字段 #指定字段的属性:read_only = 'True' read_only_fields = ('leader', 'tester') #模型类字段修改 extra_kwargs = { 'leader': { 'write_only': True, 'error_messages': {'max_length': '最大长度不超过50'} } }
四、参数总结
-
选项参数
max_length 最大长度
min_length 最小长度
allow_blank 是否允许为空
trim_whitesspaces 是否截断空白字符
max_value 最小值
min_value 最大值
-
通用参数
read_only 表明该字段仅用于序列化输出,默认False
write_only 表明该字段仅用于反序列化输入,默认False
required 表明该字段在反序列化时必须输入,默认True
default 反序列化时使用的默认值
allow_null 表明该字段是否允许传入None,默认False
validators 该字段使用校验器
error_messages 包含错误编号与错误信息的字典
label 用于html展示API页面时,显示的字段名称
help_text 用于html展示API页面时,显示的字段帮助提示信息
五、关联字段序列化
- 子表中关联字段序列化
- PrimaryKeyRelatedField
数据库模型中的外键字段,默认会生成PrimaryKeyRelatedField序列化字段,序列化输出的为外键ID值
- PrimaryKeyRelatedField

-
- StringRelatedField
此字段将被序列化为关联对象字符串表达形式(即__str__方法返回值)
- SlugRelatedField
- StringRelatedField
此字段将被序列化为关联对象的指定字段数据
-
- 使用关联对象的序列化器
from rest_framework import serializers from interfaces.models import Interfaces from projects.serializer import ProjectsModelSerializer class InterfacesModelSerializers(serializers.ModelSerializer): # 1、数据库模型中的外键字段,默认会生成PrimaryKeyRelatedField序列化字段 # 2、序列化输出的值为外键的ID值 # 3、StringRelatedField,此字段将被序列化为关联对象字符串表达形式(即__str__方法返回值) # project = serializers.StringRelatedField(label="所属项目", slug_field='tester') # 4、StringRelatedField,此字段将被序列化为关联对象的指定字段数据 # project = serializers.SlugRelatedField(slug_field='tester')
# 5、使用关联对象的序列化器 project = ProjectsModelSerializer(label='所属项目', read_only=True ) class Meta: model = Interfaces fields = "__all__"
- 父表中关联字段序列化
#父表中默认不会生成关联字段(从表),可以手动指定,字段名默认为:子表模型类名小写_set interfaces_set = serializers.StringRelatedField(many=True)
六、痛点
- requset请求只接收json数据
- 返回数据只有json格式
7、Request
- 对Django中的HttpRequesr进行了拓展
- 会根据请求头中的Content-Type,自动进行解析
- 无论前端发送那种格式的数据,都可以以相同的方式读取
- request.data
- 类似于Django中的request.POST和request.FILES
- 可以对POST、PUT、PATCH的请求体参数进行解析
- 不仅支持form传参,也支持json格式传参
- request.query_params
- 类似于Django中的request.GET
- 获取查询字符串参数
- 支持Django HTTPRequest中的所有的对象和方法
8、Response
- 对Django中的HttpResponse进行了拓展
- 会根据请求头中的Accept,自动转化响应数据到对应格式
- 如果请求头中未设置Accept,则会蚕蛹默认方式处理响应数据(默认返回json格式)
- 指定响应默认渲染类
在全局配置文件中setting.py
#DRF框架所有的全局配置都放在REST_FRAMEWORK这个字典中 REST_FRAMEWORK = { #默认响应渲染类 'DEFAULT_RENDERER_CLASSES': ( #json渲染器为第一优先级 'rest_framework.renderers.JSONRenderer', #可浏览的API渲染器为第二优先级 'rest_framework.renderers.BrowsableAPIRenderer', ) }
- Response(data, status=None, template_name=None, headers=None, content_type=None)
- 参数说明
- data
- 序列化处理后的数据
- 一般为serializer.data(python基本数据类型,嵌套字典的列表)
- status
- 状态码,默认200
- template_name
- 模板名称,使用HTMLRenderer渲染时需指明
- headers
- 用于存放响应头信息的字典
- content_type
- 响应头中的Content_type
- 通常此参数无需设置,会自动根据前端所需类型来设置该参数
- data
def post(self, request):
"""新增项目"""
#当视图继承APIView之后,请求方法实例第二个参数为Request对象,是对django中HTTPRequest对象的扩展
serializer = ProjectsSerializer(data=request.data)
#调用序列化对象的is_valid方法,开始校验前端数据
#校验成功则返回True,否则返回False
#raise_exception=True,那么校验失败会抛出异常
try:
serializer.is_valid(raise_exception=True)
except Exception as e:
return Response(serializer.errors)
#当调用is_valid方法之后才可以调用errors属性,获取校验的错误提示
# 校验成功之后的数据,可以使用validated_data来获取
#1、如果在创建序列化器对象时,只给data传参,那么调用save()方法,实际调用的是序列化器的create()方法
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)

浙公网安备 33010602011771号