day72:drf:反序列化功能&模型类序列化器Modelserializer&
目录1.续:反序列化功能(5-8) 1.用户post类型提交数据,反序列化功能的步骤 2.反序列化功能的局部钩子和全局钩子 局部钩子和全局钩子在序列化器中的使用 反序列化相关校验的执行顺序 3.反序列化的数据保存功能 4.反序列化的数据更新功能 5.Field字段参数:read_only和write_only 6.Field字段参数:partial参数 2.模型类序列化器的使用:Modelserializer 1.Modelserializer的简单介绍 2.Modelserializer的使用 3.drf:视图相关 1.APIView 2.APIView中的request 3.APIView中的response 1.续:反序列化功能(5-8)前文:反序列化功能 用户post类型提交数据,反序列化功能的步骤class Student(View): def get(self,request): ... post(self,request): '''1.获取用户在前端输入的数据''' recv_data = { 'name':request.POST.get('),ageclass_nulldescription2.实例化序列化器类,生成序列化器类对象,并将我们获取的数据传进去完成对数据的反序列化 ser = StudentSerizlizer(data=recv_data) 3.校验,全部通过得到True,一个字段错了都是得到False''' print(ser.is_valid()) 4.所有字段的错误信息(ser.errors) ---------------------------------------------------------------''' 5.反序列化完成之后的数据(ser.validated_data) 6.将反序列化后的数据添加到数据库中 ret = models.Student.objects.create( **ser.validated_data ) 7.反序列化的数据已经存储到数据库中,但是现在需要前端显示出我们新添加的数据''' 按照接口规范:如果post请求提交保存了一条记录,那么要将新添加的数据再响应回去 serializer = StudentSerializer(instance=ret) print(serializer.data) # 序列化完成后的数据 8.将序列化完成后的数据返回给前端,并设置safe和ensure_ascii参数return JsonResponse(serializer.data,safe=False,json_dumps_params={"ensure_ascii":False}) 反序列化功能的局部钩子和全局钩子1.局部钩子和全局钩子在序列化器中的使用StudentSerizlizer(serializers.Serializer): name = serializers.CharField(max_length=4,validators=[check666,]) age = serializers.IntegerField(max_value=18) class_null = serializers.CharField() required=False,allow_null=True允许字段为空,也就是不用传递过来这个data description = serializers.CharField(required=False,allow_null=True) allow_blank=True 允许只为空字符串 description = serializers.CharField(allow_blank=True) 局部钩子:针对单个属性对应的数据进行校验''' def validate_name(self,val): val就是你对应字段的内容,函数名固定写法:validate_字段名 if 777' in val: raise serializers.ValidationError(不能有777) return val 如果没有错误,需要return这个属性数据 全局钩子: 主要是针对多个属性数据进行校验 validate(self,data): data是反序列化后得到的字典print(data) OrderedDict([('name','c778'),('age',6),('class_null','1'),('description','123')]) age = data.get() class_null = data.get() if age == class_null: age和class——null不能相等return data 如果没有错误,全局钩子要return所有数据 2.反序列化相关校验的执行顺序举个例子,代码如下所示 StudentSerizlizer(serializers.Serializer): 1.字段限制 name = serializers.CharField(max_length=4,1)">) 2.局部钩子 validate_name(self,val): pass validate_age(self,1)">pass 3.全局钩子 pass 执行顺序: 1.先执行name中CharField参数中的规则 2.执行name的局部钩子函数 3.执行age的IntegerField参数中的规则 4.执行age的局部钩子函数 5.执行全局钩子函数 Tip:is_valid中的raise_exception参数serializer.is_valid(raise_exception=True) 等于True会主动抛出异常
反序列化的数据保存功能反序列化的数据保存,一共有两种方式: 方式一:直接在视图中保存方式1:直接在视图中保存 方式二:视图中通过save方法来触发序列化器类中的create方法方式2 save+create 反序列化的数据更新功能在序列化器中定义update方法来数据的更新 StudentSerizlizer(serializers.Serializer): name = serializers.CharField(max_length=4,1)">) ... 做更新动作 update(self,instance,validated_data): instance,validated_data?????print(instance) id=2 的模型类对象 print(validated_data) 反序列化后的数据 instance.name = validated_data[] instance.age = validated_data[] instance.class_null = validated_data[] instance.description = validated_data[] instance.save() instance 视图部分 put(self,request): 要更新的数据 data =id': 2,1)">xx':8sex:0,1)">9)) instance=obj用来指定这个save()触发的是序列化器中的update方法,而不是create方法,data就是你要更新的数据 s_obj = StudentSerizlizer(instance=obj,data=data) 判断反序列化之后的数据是否合法 s_obj.is_valid(): s_obj.save() 触发序列化器类的update方法 数据错误}) Field字段参数:read_only和write_onlyread_only和write_only是field字段里面的参数,也是用来对字段做限制的 from rest_framework import serializers StudentSerizlizer(serializers.Serializer): read_only=True,序列化时序列化出该字段数据,反序列化校验时不要校验这个数据 id = serializers.IntegerField(read_only=True) name = serializers.CharField(max_length=4write_only=True,序列化时不序列化这个字段数据,反序列校验时需要客户端传递这个数据过来进行校验 age = serializers.IntegerField(max_value=18,write_only=True) class_null = serializers.CharField() description = serializers.CharField(allow_blank=True) 视图部分这样写: from django.shortcuts render from django.views View from students models from .serializers StudentSerizlizer from django.http JsonResponse StudentView(View): models.Student.objects.all() serializer = StudentSerizlizer(instance=all,many=True) :False}) (request.POST) data =data) serializer.is_valid() (serializer.errors) print(正确数据:'}) Field字段参数:partial参数partial参数默认为False,若partial=True则代表只需要校验传入给序列化器的数据(data),其他的字段不校验.适用于部分数据更新 应用场景:
如果用户在前端提交数据时,必须要将五个字段都提交,否则就会报错。 但是在现实应用场景下,有很多情况是不需要将五个字段全部提交的。比如数据更新 这个时候想要更改,但是序列化器的代码已经成型了,不太好进行修改。 【eg:提交需要提交5个字段,更新提交2个字段】 chao':18 } partial=True:只需要校验传入给序列化器的数据(data),其他的字段不校验.适用于部分数据更新 serializer = StudentSerizlizer(data=data,partial=True) serializer.is_valid() ss': kk'}) 模型类序列化器的使用:Modelserializer1.Modelserializer的简单介绍
ModelSerializer与常规的Serializer相同,但提供了:
2.Modelserializer的使用models.py? .... serializers.py serializers from students.models Student StudentModelSerializer(serializers.ModelSerializer): 如果模型类序列化器,必须 1.声明本次调用是哪个模型,2.模型里面的哪些字段 Meta: model = Student fields = [","] fields = "__all__" # 表示操作模型中的所有字段 添加额外的验证选项 exclude = [',] 排除字段 extra_kwargs =":{write_only:True,},1)">read_onlyStudentViewSet(View): request.POST serializers = StudentsSerializer(data=data) status = serializers.is_valid() student = serializers.save() 上面使用的ModelSerializer,所以不需要我们自己写create方法了 (student) msghenhao'}) drf:视图相关1.APIView原来的视图都是继承View类 get: pass ...... 而drf提供了一个APIView,如下所示 HttpResponse from rest_framework.views APIView from rest_framework.response Response """ 1.drf提供的请求和响应类只能在drf封装过的子视图类中使用,也就是说不能再django.view.View中使用 2.只要类视图直接或者间接继承了APIView,则视图方法中使用的request,就是rest_framework.request.Request,同时,只有在APIVIew的子视图类中才可以使用rest_framework.respone.Response """ StudentAPIView(APIView): class StudentAPIView(View): #之前的写法 (request) <rest_framework.request.Request object at 0x11d733e90> return Response({ok'}) 2.APIView中的request
REST framework 提供了Parser解析器,在接收到请求后会自动根据Content-Type指明的请求数据类型(如JSON、表单等)将请求数据进行parse解析,解析为类字典[QueryDict]对象保存到Request对象中。这里我们可以自行写一个接口测试一下django原来的模式是解析不了json数据的,drf可以解析。但是需要注意的是:客户端如果传递过来的是json数据,那么request.data获取到的字典类型数据,不是querydict类型,也就没有了getlist方法,多选的数据,通过get就能取出来。
无论前端发送的哪种格式的数据,我们都可以以统一的方式读取数据。 APIView UserView(APIView): 当我们访问http://127.0.0.1:8001/req/students/?age=100print(request.GET) <QueryDict: {'age': ['100']}> print(request.query_params) request.GET和request.query_params是等价的 xxxxx}) (request) 1.当发送的数据格式为urlencoded类型时,request.POST和request.data等价 2.当发送过来的是json类型数据时,我们使用request.data属性能够获取到数据,request.data是无法获取json数据的 ''' print(request.data) {'username': 'xxxx','password': '123'},普通字典类型 request.data能够获取到客户端发送过来的json类型数据,但是得到的结果为普通字典类型,但是如果是多选数据,不能使用getlist方法获取 '}) 3.APIView中的response1.response介绍
我们后端如果通过Response来想用数据时,通过postman发送get请求获取数据,你会发现得到的是纯json数据,但是通过浏览器访问时会的到一个页面。这是为什么呢?drf的APIView在响应内容的时候会自动通过请求头中的浏览器信息来进行数据的回复(Response),如果是浏览器,那么返回的就是个页面(当然我们也可以不让他返回页面,可设置的,后面说)如果不是浏览器,给你返回的就是纯json数据。这是由drf中配置的两个不同的响应类产生的效果,看下面的配置。
查看drf的默认配置 settings 用户配置替换drf内部配置的写法 REST_FRAMEWORK = { DEFAULT_RENDERER_CLASSES': ( 默认响应渲染类 rest_framework.renderers.JSONRenderer json渲染器 rest_framework.renderers.BrowsableAPIRenderer 浏览器API渲染器 ) } 2.response参数解释引入Response Response response里面的相关参数 return Response({},status=201,template_name=None,headers=None,content_type=None) {}:响应的数据... status:状态码 template:用于自定义浏览器的响应页面 headers:自定义响应头键值对 content_type:.... '''
3.状态码大全查看所有状态码 status HTTP_100_CONTINUE = 100 HTTP_101_SWITCHING_PROTOCOLS = 101 HTTP_200_OK = 200 HTTP_201_CREATED = 201 HTTP_202_ACCEPTED = 202 HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203 HTTP_204_NO_CONTENT = 204 HTTP_205_RESET_CONTENT = 205 HTTP_206_PARTIAL_CONTENT = 206 HTTP_207_MULTI_STATUS = 207 HTTP_208_ALREADY_REPORTED = 208 HTTP_226_IM_USED = 226 HTTP_300_MULTIPLE_CHOICES = 300 HTTP_301_MOVED_PERMANENTLY = 301 HTTP_302_FOUND = 302 HTTP_303_SEE_OTHER = 303 HTTP_304_NOT_MODIFIED = 304 HTTP_305_USE_PROXY = 305 HTTP_306_RESERVED = 306 HTTP_307_TEMPORARY_REDIRECT = 307 HTTP_308_PERMANENT_REDIRECT = 308 HTTP_400_BAD_REQUEST = 400 HTTP_401_UNAUTHORIZED = 401 HTTP_402_PAYMENT_REQUIRED = 402 HTTP_403_FORBIDDEN = 403 HTTP_404_NOT_FOUND = 404 HTTP_405_METHOD_NOT_ALLOWED = 405 HTTP_406_NOT_ACCEPTABLE = 406 HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407 HTTP_408_REQUEST_TIMEOUT = 408 HTTP_409_CONFLICT = 409 HTTP_410_GONE = 410 HTTP_411_LENGTH_REQUIRED = 411 HTTP_412_PRECONDITION_FAILED = 412 HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413 HTTP_414_REQUEST_URI_TOO_LONG = 414 HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415 HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416 HTTP_417_EXPECTATION_FAILED = 417 HTTP_418_IM_A_TEAPOT = 418 HTTP_422_UNPROCESSABLE_ENTITY = 422 HTTP_423_LOCKED = 423 HTTP_424_FAILED_DEPENDENCY = 424 HTTP_426_UPGRADE_REQUIRED = 426 HTTP_428_PRECONDITION_REQUIRED = 428 HTTP_429_TOO_MANY_REQUESTS = 429 HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431 HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451 HTTP_500_INTERNAL_SERVER_ERROR = 500 HTTP_501_NOT_IMPLEMENTED = 501 HTTP_502_BAD_GATEWAY = 502 HTTP_503_SERVICE_UNAVAILABLE = 503 HTTP_504_GATEWAY_TIMEOUT = 504 HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505 HTTP_506_VARIANT_ALSO_NEGOTIATES = 506 HTTP_507_INSUFFICIENT_STORAGE = 507 HTTP_508_LOOP_DETECTED = 508 HTTP_509_BANDWIDTH_LIMIT_EXCEEDED = 509 HTTP_510_NOT_EXTENDED = 510 HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511 Tip:响应状态码的两种书写方式status 响应状态码方式一 '},status=201) 响应状态码方式二 (编辑:李大同) |