您的当前位置:首页 > 国际 > 正文

观点:drf——反序列化校验源码(了解)、断言、drf之请求和响应、视图之两个视图基类

  • 2023-05-22 22:22:06 来源:博客园


(相关资料图)

1.模块与包
# 模块与包模块:一个py文件 被别的py文件导入使用,这个py文件称之为模块,运行的这个py文件称之为脚本文件    包:一个文件夹下有__init__.py        # 模块与包的导入问题"""1.导入模块有相对导入和绝对导入,绝对导入的路径是从环境变量开始的2.导入任何模块,如果使用绝对导入,都是从环境变量开始导起3.脚本文件执行的路径,会自动加入环境变量4.相对导入的话,是从当前py文件开始计算的5.以脚本运行的文件,不能使用相对导入,只能用绝对导入"""
2.反序列化校验源码分析(了解)
# 序列化类的校验功能局部钩子:必须 validate_字段名    全局钩子:validate        # 入口ser.is_valid 才做的校验---》入口    先从自己写的BookSerializer类中找is_valid方法----》再到继承的父类Serializer中找---》再到它的父类BaseSerializer中找----》is_valid---》还继承了Field    """BookSerializer类中的is_valid方法"""    def is_valid(self, *, raise_exception=False):            # self中没有_validated_data,只有执行完后,才有(校验过后的数据)            if not hasattr(self, "_validated_data"):                try:                    # 核心---》这一句                    # 想看它的源代码,按住ctrl+鼠标点击是不对的---》只能找当前类的父类,要从根上开始找                    self._validated_data = self.run_validation(self.initial_data)                except ValidationError as exc:                    self._validated_data = {}                    self._errors = exc.detail                else:                    self._errors = {}            if self._errors and raise_exception:                raise ValidationError(self.errors)            return not bool(self._errors)           """    self.run_validation(self.initial_data)    在Serializer中有run_validation这个方法先执行这个    """    def run_validation(self, data=empty):             # 局部钩子            value = self.to_internal_value(data)            try:                # 全局钩子                value = self.validate(value) # BookSerializer只要写了,优先执行它的            except (ValidationError, DjangoValidationError) as exc:                raise ValidationError(detail=as_serializer_error(exc))            return value            """    局部钩子    self.to_internal_value(data)---》Serializer类的方法    """    def to_internal_value(self, data):            for field in fields: #序列化类中写的一个个的字段类的对象列表                # 一个field是name对象,field.field_name字符串 name                # self是谁的对象:序列化类的对象,BookSerializer的对象  validate_name                validate_method = getattr(self, "validate_" + field.field_name, None)                try:                    # 字段自己的校验规则                    validated_value = field.run_validation(primitive_value)                    if validate_method is not None:                        # 局部钩子                        validated_value = validate_method(validated_value)                except ValidationError as exc:                    errors[field.field_name] = exc.detail                except DjangoValidationError as exc:                    errors[field.field_name] = get_error_detail(exc)                except SkipField:                    pass                else:                    set_value(ret, field.source_attrs, validated_value)            if errors:                raise ValidationError(errors)            return ret        # 总结ser.is_valid--->走局部钩子的代码---》是通过反射获取BookSerializer中写的局部钩子函数,如果写了,就会执行---》走全局钩子代码---》self.validate(value)---》只要序列化类中写了,优先走自己的
3.断言
assert hasattr(self, "initial_data"), (            "Cannot call `.is_valid()` as no `data=` keyword argument was "            "passed when instantiating the serializer instance."        )# 断言某个东西是我认为的,如果不是就抛异常# 等同于if判断+抛异常def add(a,b):    return a + bres = add(8,9)# assert res == 16,Exception("不等于16")if not res == 16:    raise Exception("不等于16")print("随便")
4.drf之请求
# 视图类:APIView# 序列化组件:Serializer,ModelSerializer# drf:Request类的对象
4.1Request类对象的分析
1.datarequest.data 返回解析之后的请求体数据。类似于Django中标准的request.POST和request.FILES属性,但提供如下特性:    包含了解析之后的文件和非文件数据    包含了对POST、PUT、PATCH请求方式解析后的数据    利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据2..query_paramsrequest.query_params等同于request.GET 3.其他的属性用法跟之前一样
4.2请求能够接受的编码格式
# urlencoded# form-data# json三种都支持可以限制只能接受某种或者某几种编码格式# 限制方式一:在视图类上写--》只是局部视图类有效# 总共有三个:JSONParser,FormParser, MultiPartParser    class BookView(APIView):        parser_classes = [JSONParser, FormParser]# 限制方式二:在配置文件中写---》全局有效# drf的配置(在rest_framework的setting中),统一写成它    REST_FRAMEWORK = {        "DEFAULT_PARSER_CLASSES": [            "rest_framework.parsers.JSONParser",            # "rest_framework.parsers.FormParser",            # "rest_framework.parsers.MultiPartParser",        ],    }    # 全局配置了只支持json,局部想支持3个-只需要在局部,视图类中,写3个即可    class BookView(APIView):    parser_classes = [JSONParser, FormParser,MultiPartParser]         # 总结:能够处理的请求方式编码-优先从视图类中找    -再去项目配置文件找    -再去drf默认的配置中找
5.drf之响应5.1响应类的对象Response
# return Response({"code":100})data:响应体的内容,可以字符串,字典,列表status:http响应状态码   drf把所有响应码都定义成一个常量template_name:模板名字,用浏览器访问,看到好看的页面,用postman访问,返回正常数据-自定制页面    -根本不用    headers:响应头加数据(后面讲跨域问题再讲)-headers={"name":"lqz"}content_type:响应编码,一般不用# 三个重要的:data,status,headers
5.2响应的格式
# 默认是两种:纯json,浏览器看到的样子# 限制方式一:在视图类上写---》只是局部视图类有效# 总共有两个:JSONRenderer,BrowsableAPIRenderer    from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer    class BookView(APIView):        renderer_classes = [JSONRenderer]        # 限制方式二:在配置文件中写---》全局有效    # drf的配置,统一写成它     REST_FRAMEWORK = {        "DEFAULT_RENDERER_CLASSES": [            "rest_framework.renderers.JSONRenderer",            # "rest_framework.renderers.BrowsableAPIRenderer",        ],    }        # 全局配置了只支持json,局部想支持2个-只需要在局部,视图类中,写2个即可from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer    class BookView(APIView):        renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
6.视图之两个视图基类
# 视图类:-APIView:之前用过-GenericAPIView:GenericAPIView继承了APIView            # GenericAPIView-类属性:    queryset:要序列化的所有数据    serializer_class:序列化类        lookup_field = "pk" :查询单条时的key值     -方法:    -get_queryset():获取所有要序列化的数据【后期可以重写】        -get_serializer  : 返回序列化类        -get_object :获取单个对象                         #总结:以后继承GenericAPIView写接口1 必须配置类属性    queryset        serializer_class     2 想获取要序列化的所有数据    get_queryset()     3 想使用序列化类:    get_serializer     4 想拿单条    get_object
6.1使用APIView+序列化类+Response写接口
from rest_framework.views import APIViewfrom .serializer import BookSerialzierfrom rest_framework.response import Responsefrom .models import Book# class BookView(APIView):#     def get(self, request):#         qs = Book.objects.all()#         ser = BookSerialzier(qs, many=True)#         return Response({"code": 100, "msg": "成功", "results": ser.data})##     def post(self, request):#         ser = BookSerialzier(data=request.data)#         if ser.is_valid():#             ser.save()#             return Response({"code": 100, "msg": "成功"})#         else:#             return Response({"code": 100, "msg": ser.errors})### class BookDetailView(APIView):#     def get(self, request, pk):#         book = Book.objects.all().get(pk=pk)#         ser = BookSerialzier(book)#         return Response({"code": 100, "msg": "成功", "results": ser.data})##     def put(self, request, pk):#         book = Book.objects.get(pk=pk)#         ser = BookSerialzier(data=request.data, instance=book)#         if ser.is_valid():#             ser.save()#             return Response({"code": 100, "msg": "更新成功"})#         else:#             return Response({"code": 100, "msg": ser.errors})
6.2 使用GenericAPIView+序列化类+Response写接口
class BookView(GenericAPIView):    queryset = Book.objects.all()    serializer_class = BookSerialzier    def get(self, request):        qs = self.get_queryset()        ser = self.get_serializer(qs, many=True)        return Response({"code": 100, "msg": "成功", "results": ser.data})    def post(self, request):        ser = self.get_serializer(data=request.data)        if ser.is_valid():            ser.save()            return Response({"code": 100, "msg": "成功"})        else:            return Response({"code": 100, "msg": ser.errors})class BookDetailView(GenericAPIView):    queryset = Book.objects.all()    serializer_class = BookSerialzier    def get(self, request, pk):        book = self.get_object()        ser = self.get_serializer(book)        return Response({"code": 100, "msg": "成功", "results": ser.data})    def put(self, request, pk):        book = self.get_object()        ser = self.get_serializer(data=request.data, instance=book)        if ser.is_valid():            ser.save()            return Response({"code": 100, "msg": "更新成功"})        else:            return Response({"code": 100, "msg": ser.errors})

标签:

推荐阅读

观点:drf——反序列化校验源码(了解)、断言、drf之请求和响应、视图之两个视图基类

1 模块与包```python 模块与包模块:一个py文件被别的py文件导入使用,这个py文件称之为模块,运行的这个p

微头条丨中英保险百万医疗险怎么样?有必要买吗?

整体比较优秀。 中英保险百万医疗险是一款提供百万医疗保障的保险,由中英人寿保险有限公司提供。该保险主

环球新资讯:上海临港出新规划 L3级别车辆可上高速

汽车已经成了大多数人生活中必备的交通工具了,随着人们对汽车需求量的加大,汽车公司也多了起来。每天都有一

天天视讯!董事长领年薪11倍罚单 卓锦股份面临投资者索赔

卓锦股份(688701)日前对外披露,公司收到浙江证监局下发的《行政处罚决定书》。从被立案调查到正式被行政

每日关注!慈利县第29期中青年干部培训班开班

红网时刻张家界5月22日讯(慈利站记者邓锦李晓敏)5月22日,慈利县第29期中青年干部培训班在县委党校开班,

猜您喜欢

【版权及免责声明】凡注明"转载来源"的作品,均转载自其它媒体,转载目的在于传递更多的信息,并不代表本网赞同其观点和对其真实性负责。亚洲房产网倡导尊重与保护知识产权,如发现本站文章存在内容、版权或其它问题,烦请联系。 联系方式:8 86 239 5@qq.com,我们将及时沟通与处理。

商业