博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
rest_framework ---APIView
阅读量:5237 次
发布时间:2019-06-14

本文共 4294 字,大约阅读时间需要 14 分钟。

APIView源调用流程

1.首先从django项目跟url开始

我们已get请求publish页面为例,如下先在跟目录找到

r'^publish/'  ---->执行对应的函数  views.PublishView.as_view()

urls.py:

from django.conf.urls import url from django.contrib import admin from app01 import views
urlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'^publish/',views.PublishView.as_view())]

查找顺序:views.py----->PublishView------>APIView

文字说明:先查找views.py下的PublishView,看看自定义类是否有as_view方法,没有就开始向父类APIView查找,在APIView中有as_view方法,其实通过32行

     代码我们知道APIView执行的还是它父类View中的as_view方法返回了一个内嵌的view函数,这个函数执行的结果我们可以看到得到的是一个

      self.dispatch(request, *args, **kwargs),这个self很关键,通过 self = cls(**initkwargs),我们知道这个self就是调用这个类方法的一个实例

    谁来调用这个函数self就是谁的实例,所以在我们这个例子中self指代的及时PublishView的实例对线,所以在调用dispatch方法先从自定义的PublishView中找

    ,我们这个class中没有dispatch所以开始找它的父类APIView,在APIView中找到了我们需要的dispatch,所以开始执行这个分发,走到这里我们可以看到

    rest_framework在APIView接口中和CBV的区别就是APIVIew自定义了一个dispatch对CBV的view方法中的dispatch进行了一个拦截,有点类似我们组件中的

    通用父类和自定义配置类

1 # views.py: 2  3 from rest_framework.views import APIView 4  5 class PublishView(APIView): 6  7     def get(self,request): 8         pass 9 10 11     def post(self,request):12         pass13 14 # rest_framework/views.py15 16 class APIView(View):17     settings = api_settings18     schema = DefaultSchema()19 20     @classmethod21     def as_view(cls, **initkwargs):22         23         if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):24             def force_evaluation():25                 raise RuntimeError(26                     'Do not evaluate the `.queryset` attribute directly, '27                     'as the result will be cached and reused between requests. '28                     'Use `.all()` or call `.get_queryset()` instead.'29                 )30             cls.queryset._fetch_all = force_evaluation31 32         view = super(APIView, cls).as_view(**initkwargs)33         view.cls = cls34         view.initkwargs = initkwargs35 36         return csrf_exempt(view)37   38   39 def dispatch(self, request, *args, **kwargs):40     41     self.args = args42     self.kwargs = kwargs43     request = self.initialize_request(request, *args, **kwargs)44     self.request = request45     self.headers = self.default_response_headers  # deprecate?46 47     try:48         self.initial(request, *args, **kwargs)49 50         # Get the appropriate handler method51         if request.method.lower() in self.http_method_names:52             handler = getattr(self, request.method.lower(),53                               self.http_method_not_allowed)54         else:55             handler = self.http_method_not_allowed56 57         response = handler(request, *args, **kwargs)58 59     except Exception as exc:60         response = self.handle_exception(exc)61 62     self.response = self.finalize_response(request, response, *args, **kwargs)63     return self.response
class View(object):       http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']    @classonlymethod    def as_view(cls, **initkwargs):               for key in initkwargs:            if key in cls.http_method_names:                raise TypeError("You tried to pass in the %s method name as a "                                "keyword argument to %s(). Don't do that."                                % (key, cls.__name__))            if not hasattr(cls, key):                raise TypeError("%s() received an invalid keyword %r. as_view "                                "only accepts arguments that are already "                                "attributes of the class." % (cls.__name__, key))        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        # take name and docstring from class        update_wrapper(view, cls, updated=())        # and possible attributes set by decorators        # like csrf_exempt from dispatch        update_wrapper(view, cls.dispatch, assigned=())        return view

 

转载于:https://www.cnblogs.com/dingyutao/articles/9395211.html

你可能感兴趣的文章
Java 内部类
查看>>
{面试题7: 使用两个队列实现一个栈}
查看>>
【练习】使用事务和锁定语句
查看>>
centos7升级firefox的flash插件
查看>>
Apache Common-IO 使用
查看>>
评价意见整合
查看>>
二、create-react-app自定义配置
查看>>
Android PullToRefreshExpandableListView的点击事件
查看>>
系统的横向结构(AOP)
查看>>
linux常用命令
查看>>
NHibernate.3.0.Cookbook第四章第6节的翻译
查看>>
使用shared memory 计算矩阵乘法 (其实并没有加速多少)
查看>>
Django 相关
查看>>
git init
查看>>
训练记录
查看>>
IList和DataSet性能差别 转自 http://blog.csdn.net/ilovemsdn/article/details/2954335
查看>>
Hive教程(1)
查看>>
第16周总结
查看>>
C#编程时应注意的性能处理
查看>>
Fragment
查看>>