zoukankan      html  css  js  c++  java
  • cbv请求分析

    CBV源码分析

    DRF中中所有视图都是基于CBV形式完成, 所以分析其cbv源码, 了解drf的基本请求流程就比较有必要了.

    urls.py
    """下面是一个通用的url路由""""
    url(r'^books/$', views.Book.as_view())
    
    """as_view同样是drf视图类的入口"""
    
    views.py
    """下面是一个通用的简单的基于drf的apiview的一个视图"""
    class Book(APIView):
        def get(self, request, *args, **kwargs):
            # 这个接口提供两个接口来进行调用, 所以需要分开来进行判断
            # 判断路由中是否包含pk
            pk = kwargs.get('pk')
            # pk有值, 代表是查单本书
            if pk:
                try:
                    book = models.Book.objects.get(pk=pk, is_delete=False)
                except models.Book.DoesNotExist:
                    return Response({
                        'status': 1,
                        'msg': '图书不存在'
                    })
                ser_data = serializers.BookModelSerializer(book).data
            # 当没有查询单本书时, 即pk不存在的话, 默认进行查询所有图书
            else:
                books = models.Book.objects.filter(is_delete=False)  # 要找没有被删除的书籍
                ser_data = serializers.BookModelSerializer(books, many=True).data  # 不要忘记添加many=True的条件, 序列化多个对象对象
            return Response({
                'status': 0,
                'msg': '查询成功',
                'result': ser_data
            })
    

    as_view入口分析

    首先drf的apiview是继承自django中View, 并重写了as_view方法, 也就相当于改写了入口方法.

    	@classmethod
        def as_view(cls, **initkwargs):
            view = super().as_view(**initkwargs)
            view.cls = cls
            view.initkwargs = initkwargs
    		# 直接禁用了csrf认证, 所以我们的post请求可以不携带csrftoken参数了.
            return csrf_exempt(view)
    

    上面是APIView的as_view方法, 重写的内容很简单, 只是将csrf认证禁用了, 并进行了一些参数的初始化工作. 接下来是重点, as_view方法调用了父类的as_view方法, 返回的结果才是url匹配后真正执行的内容, 也就是调用了dispatch方法来分发.

    dispatch分析

    """django的View的as_view方法"""
    @classonlymethod
        def as_view(cls, **initkwargs):
            def view(request, *args, **kwargs):
                self = cls(**initkwargs)
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                self.request = request
                self.args = args
                self.kwargs = kwargs
                # 视图类调用的方法.
                return self.dispatch(request, *args, **kwargs)
            view.view_class = cls
            view.view_initkwargs = initkwargs
            update_wrapper(view, cls, updated=())
            update_wrapper(view, cls.dispatch, assigned=())
            return view
    

    上面的源码部分清晰的看出了, 最后我们的路由匹配成功后, 最后走的是as_view内层的view方法, 也就是说调用了view类的dispatch方法, 而APIView正式重写了这个dispatch方法, 在这里做了许多的事, 因此可以说, dispatch才是drf中APIView的真正入口函数.

        def dispatch(self, request, *args, **kwargs):
            self.args = args
            self.kwargs = kwargs
            # 重新封装了request对象
            request = self.initialize_request(request, *args, **kwargs)
            self.request = request
            self.headers = self.default_response_headers  # deprecate?
    
            try:
                # 这里做了各种初始化工作, 包括频率,认证, 权限等的校验.
                self.initial(request, *args, **kwargs)
                # 和django中的一样, 需要符合对应的8种http请求方法, 才能正确走到对应的视图函数进行处理.
                if request.method.lower() in self.http_method_names:
                    handler = getattr(self, request.method.lower(),
                                      self.http_method_not_allowed)
                else:
                    handler = self.http_method_not_allowed
    		   # 调用视图函数来处理具体的业务逻辑
                response = handler(request, *args, **kwargs)
    
            except Exception as exc:
                # 自带的异常处理.
                response = self.handle_exception(exc)
    		# 处理返回的响应
            self.response = self.finalize_response(request, response, *args, **kwargs)
            return self.response
    
  • 相关阅读:
    php通过某个日期段的周几,获取选中周几对应的日期
    thinkphp 使用paginate分页搜索带参数
    php小程序登录时解密getUserInfo获取openId和unionId等敏感信息
    微信小程序使用wxParse,解决图片显示路径问题
    php对二维数据排序
    微信小程序下拉框之二维数组或对象
    php获取指定月份月初和月末的时间戳
    WPF中实现自定义虚拟容器(实现VirtualizingPanel)
    SQL Server数据库ROW_NUMBER()函数使用详解
    WPF后台设置xaml控件的样式System.Windows.Style
  • 原文地址:https://www.cnblogs.com/yscl/p/11930762.html
Copyright © 2011-2022 走看看