序列化 => 后台数据到前台,反序列化 => 前台数据写到后台数据库
将类定义在一个类的内部,被定义的类就是内部类json
内部类及内部类的名称空间,能够直接被外部类访问网络
经过内部类的名称空间,给外部类额外拓展一些特殊的属性(配置),典型的Meta内部类 - 配置类app
class Book(model.Model): class Meta: db_model = "owen_book" # 配置自定义表名 class BookSerializer(serializers.ModelSerializer): class Meta: model = "Book" # 配置序列化类绑定的Model表
drf的响应类Response内部属性有:post
class Response(SimpleTemplateResponse): def __init__(self, data=None, status=None, template_name=None, headers=None, exception=False, content_type=None):
data:响应的数据 - 空、字符串、数字、列表、字典、布尔ui
status:网络状态码spa
template_name:drf本身也能够支持先后台不分离的返回页面,可是不能和data共存(不会涉及到)rest
headers:响应头code
exception:是否有异常响应(若是异常能够赋值为True,没什么用)对象
content_type:响应的结果类型(响应式data默认是application/json)
常见响应:
from rest_framework import status # 正常响应 Response( data={ 'status': 0, 'msg': 'ok', 'result': '正常数据' } ) # 异常响应 Response( data={ 'status': 1, 'msg': '客户端错误提示', }, status=status.HTTP_400_BAD_REQUEST, exception=True )
序列化serializers类继承的BaseSerializer类中初始化参数有如下的:
def __init__(self, instance=None, data=empty, **kwargs): pass
instance:是要被赋值对象的, - 对象类型数据赋值给instance
data:是被赋值数据的,- 请求来的数据赋值给data
kwargs:内部有三个属性:many、partial、context
many:操做的对象或数据是单个或多个
partial:在修改需求时使用,能够将全部的校验字段required校验规则设置为False
context:用于视图类和序列化类直接传参使用
常见使用:
# 单查接口 UserModelSerializer(instance = user_obj) # 群查接口 UserModelSerializer(instance = user_query, many=True) # 增接口 UserModelSerializer(data = request.data) # 总体改接口 UserModelSerializer(instance = user_obj, data = request.data) UserModelSerializer(instance = user_obj, data = requset.data, partial = True) # 删接口用不到序列化类
class UserAPIView(APIView): def post(self, request, *args, **kwargs): # 单增 # 1)将前台请求的数据交给序列化类处理 # 2)序列化类执行校验方法,对前台提交的全部数据进行数据校验:校验失败就是异常返回,成功才能继续 # 3)序列化组件完成数据入库操做,获得入库对象 # 4)响应结果给前台 serializer = serializers.UserModelSerializer(data=request.data) if serializer.is_valid(): # is_valid校验 # 校验成功 => 入库 => 正常响应 obj = serializer.save() # save内部入库 return Response({ 'status': 0, 'msg': 'ok', 'result': serializers.UserModelSerializer(obj).data # 新增的值返回 }, status=status.HTTP_201_CREATED) else: # 校验失败 => 异常响应 return Response({ 'status': 1, 'msg': serializer.errors, # errors错误信息 }, status=status.HTTP_400_BAD_REQUEST)
开发流程:
在models类中自定义字段,在serializer类中自定义写字段
能够在extra_kwargs中写基础的校验规则,也能够省略
制定局部钩子与全局钩子,全局钩子在上述全部校验后再校验
一、不论是序列化仍是反序列化字段,都必须在field中进行声明,没有声明的不会参与任何过程(数据会被丢弃)
二、用read_only 表示只读,用write_only表示只写,不标注二者默认表明便可读也可写
三、models类中的自定义的字段@property声明的默认就是只读read_only
@property def gender(self): return self.get_sex_display()
四、自定义的只写字段,在serializer类中须要本身手动声明write_only,serializer中自定义的字段必须明确write_only不然会报错,由于序列化会从model中强行反射自定义的字段,而model中没有该字段就会报错,而对于model中已经有的字段,在serializer类中再次声明会对model原有的字段进行覆盖,能够不明确write_only表示可读可写,而且要写在Meta上方同级的
re_password = serializers.CharField(write_only=True)
五、用extra_kwargs来为写的字段制定基础校验规则,能够在extra_kwargs中使用required表明是否必须参与写操做,有默认值和能够为空的时该值为False,反之为True,能够手动修改
# 制定简易基础校验规则查看有哪些规则 # serializers.DecimalField.max_value # serializers.CharField.max_length extra_kwargs = { 'name': { 'required': True, 'max_length': 32, 'error_messages': { # 能够被国际化配置替代 'max_length': '太长' } } }
六、每个字段咱们均可以自定义校验规则,使用局部钩子 validate_字段名(self, value) 方法来自定义校验规则,成功在返回value,失败在抛出exceptions.ValidationError('异常信息')异常
七、咱们也可使用全局钩子对好几个字段进行校验,好比password与re_password,使用validate(self, attrs),成功返回attrs,失败则抛出异常exceptions.ValidationError('异常信息')
from rest_framework import serializers from . import models from rest_framework import exceptions # 制定简易基础校验规则查看有哪些规则 # serializers.DecimalField.max_value # serializers.CharField.max_length class UserModelSerializer(serializers.ModelSerializer): # 自定义字段,覆盖model中的字段,model中没有则必须写write_only=True pwd = serializers.CharField(max_length=8, min_length=4, write_only=True) re_pwd = serializers.CharField(max_length=8, min_length=4, write_only=True) class Meta: model = models.User # 将全部的字段都写在fields中 fields = ['name', 'pwd', 'age', 'height', 'gender', 'img', 're_pwd'] # 自定义基础的校验规则 extra_kwargs = { 'name': { # 有默认值或者能够为空,咱们也能够限制必须提供 'required': True, 'max_length': 8, 'error_messages': { # 能够被国际化配置替代 'max_length': '太长' } } } # 局部与全局钩子与Meta同级,属性序列化类的 # 自定义单个字段校验在局部钩子中校验,用validate_字段名(self, value) def validate_height(self, value): print(value) if value < 170: raise exceptions.ValidationError('过矮了') else: return value # 多字段之间校验用全局钩子,validate(self, attrs) attrs是字段值的字典 def validate(self, attrs): pwd = attrs.get('pwd') # 只拿出来校验 re_pwd = attrs.pop('re_pwd') # 必须pop出来,不能存入数据库中 if pwd != re_pwd: raise exceptions.ValidationError({'re_pwd': '两次密码不一致!'}) else: return attrs