Python rest-framework 中类的继承关系(as_view)

一. 背景

最近几天一直在学习restful framework的源代码,用户请求的流程,在路由系统这块遇到一个疑问,关于类的继承关系,当请求进来到路由这块,执行as_view()方法的时候,为什么会运行父类View的as_view()方法再执行到APIView的dispatch方法呢?这里记录一下一遍后面方便自己查阅

二. 代码示例

1. 路由

from django.conf.urls import url
from api import views as api_view

urlpatterns = [
    url(r‘^index/‘, api_view.IndexView.as_view()),
]

2.  视图类

from rest_framework.response import  Response
from rest_framework.views import APIView

class IndexView(APIView):
    def get(self,request):
        return Response(‘...‘)

三. 源代码分析

a. APIView的as_view方法

class APIView(View):

    @classmethod
    def as_view(cls, **initkwargs):

        if isinstance(getattr(cls, ‘queryset‘, None), models.query.QuerySet):
            def force_evaluation():
                raise RuntimeError(
                    ‘Do not evaluate the `.queryset` attribute directly, ‘
                    ‘as the result will be cached and reused between requests. ‘
                    ‘Use `.all()` or call `.get_queryset()` instead.‘
                )
            cls.queryset._fetch_all = force_evaluation

        view = super(APIView, cls).as_view(**initkwargs)
        # 这里是继承了父类的方法as_view()

        view.cls = cls
        view.initkwargs = initkwargs

        return csrf_exempt(view)

# 代码太多只截取部分代码

b. super(APIView,cls).as_view(**initkwargs)执行了什么操作

# super(APIView,self) 首先找到 APIView的父类(就是类 View),然后把View类的as_view属性 转换为类 APIView的属性
# 相当于将View中的as_view()中的代码复制到API_View中的as_view中

所以最终运行 super(APIView,cls).as_view(**initkwargs)执行了View中的as_view方法

class View(object):

    http_method_names = [‘get‘, ‘post‘, ‘put‘, ‘patch‘, ‘delete‘, ‘head‘, ‘options‘, ‘trace‘]

    def __init__(self, **kwargs):

        for key, value in six.iteritems(kwargs):
            setattr(self, key, value)

    @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)
            # 运行这里吧最后执行了self.dispatch
        view.view_class = cls
        view.view_initkwargs = initkwargs

        update_wrapper(view, cls, updated=())

        update_wrapper(view, cls.dispatch, assigned=())
        return view       # 返回了view函数

原文地址:https://www.cnblogs.com/supery007/p/8432324.html

时间: 2024-11-06 12:29:27

Python rest-framework 中类的继承关系(as_view)的相关文章

在Entity Framework 中实现继承关系映射到数据库表

继承关系映射到数据库表中有多种方式: 第一种:TPH(table-per-hiaerachy) 每一层次一张表 (只有一张表) 仅使用名为父类的类型名的一张表,它包含了各个子类的所有属性信息,使用区分列(Disciriminator column)(通常内容为子类的类型名)来区分哪一行表示什么类型的数据. 第二种:TPT(Table-per-type) 每种类型都有一张表(父类及每个子类都有表) 父类.各子类各自都有一张表.父类的表中只有共同的数据,子类表中有子类特定的属性.TPT很像类的继承结

PHP中类的继承关系

在PHP中,我时常会写一个类,类写了一个共用方法,然后让子类去继承就能得到相应的功能.假设大致有这么一个父类:  1 <?php  2 class Father{  3   4     public function __construct(){  5         echo '我是父类的构造方法!';  6     }  7   8     protected function say($str = 'Hello World!'){  9         echo '说了一句话:' . $s

C++中类的继承关系梳理

人生苟且了很长时间,需要再继续努力了. 总结了C++的继承方面的关系: 朋友在面试的时候被问过一个问题,说类的继承重要的一点是什么,他没有答到点子上,后来面试官提到的是代码的复用,不用每次都重新写相同的代码,还是有道理的. 类的声明: class TableTennisPlayer{private: string firstname; string lastname; bool hashTable; public: TableTennisPlayer(const string &fn = &quo

UI基础:UI中类的继承关系图,最基本的视图分析

首先,UI中常用的UIwindow.UILabel.UIButton.UITextField属于UIView的子类.UITextField和UILabel和UIwindow自身没有初始化方法,需要使用父类的UIView的初始化方法initWithframe,UIbutton有自己的初始化方法buttonWithType:<#(UIButtonType)#>.因为UITextField和UILabel和UIWindow都需要alloc,所以它们都需要release方法,而UIButton则不需要

Python中类的内置方法与继承关系实例

1.类的内置方法 Python内部类:所谓内部类,就是在类的内部定义的类,主要目的是为了更好的抽象现实世界.例子:汽车是一个类,汽车的底盘轮胎也可以抽象为类,将其定义到汽车内中,而形成内部类,更好的描述汽车类,因为底盘轮胎是汽车的一部分. 内部类实例化方法: 方法1:直接使用外部类调用内部类方法2:先对外部类进行实例化,然后再实例化内部类 out_name = outclass_name() in_name = out_name.inclass_name() in_name.method() #

Entity Framework Code First 映射继承关系

转载 http://www.th7.cn/Program/net/201301/122153.shtml Code First如何处理类之间的继承关系.Entity Framework Code First有三种处理类之间继承关系的方法,我们将逐一介绍这三种处理方法. 1.Table Per Hierarchy(TPH): 只建立一个表,把基类和子类中的所有属性都映射为表中的列. 2.Table Per Type(TPT): 为基类和每个子类建立一个表,每个与子类对应的表中只包含子类特有的属性对

.NET Framework中重点类型的继承关系

继承关系 Object ├─Array │ └─T[] ├─ArrayList └─String .NET Framework中重点类型的继承关系

Python中类的继承及类的属性和方法总结

1.类的继承 类的继承 继承是面向对象的重要特性之一, 继承关系继承是相对两个类而言的父子关系 子类继承了父类的所有公有属性和方法, 继承,实现了代码重用 使用继承 继承可以重用已经存在的数据和行为,减少代码的重复编写, Python在类名后使用一对括号来表示继承关系,括号中的即类为父类 class Myclass(ParentClass), 如果父类定义了__init__方法,子类必须显式调用父类的__init__方法, ParentClass.__init__(self,[args...])

python 异常继承关系及自定义异常的实现

主要介绍 python 中异常的继承关系,及如何自定义异常 1. 异常的继承关系 BaseException # 所有异常的基类 +-- SystemExit # 解释器请求退出 +-- KeyboardInterrupt 用户中断执行(通常是输入^C) +-- GeneratorExit # 生成器(generator)发生异常来通知退出 +-- Exception # 常规异常的基类 +-- StopIteration # 迭代器没有更多的值 +-- StandardError # 标准错误