首页 > Windows开发 > 详细

APIView源码分析

时间:2019-03-25 21:03:54      阅读:152      评论:0      收藏:0      [点我收藏+]

APIView源代码

# 简单实例

from django.views import  View
class Books(View):
    def get(self,request, *args, **kwargs):
        print("get")
        return HttpResponse("ok")

    def dispatch(self, request, *args, **kwargs):
        print("dispatch")
        ret = super(Books,self).dispatch(request, *args, **kwargs)
        print("ret",ret)
        return  HttpResponse(ret)
# 通过url(r"books/$",views.BookView.as_view())入手

@classmethod
    def as_view(cls, **initkwargs):
        """
        Store the original class on the view function.

        This allows us to discover information about the view when we do URL
        reverse lookups.  Used for breadcrumb generation.
        """
        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)
        view.cls = cls
        view.initkwargs = initkwargs

        # Note: session based authentication is explicitly CSRF validated,
        # all other authentication is CSRF exempt.
        return csrf_exempt(view)

APIView类是继承View类,view类是from django.views import View下的View

APIView类中,我们重点了解return csrf_exempt(view)

def csrf_exempt(view_func):
    """
    Marks a view function as being exempt from the CSRF view protection.
    """
    # We could just do view_func.csrf_exempt = True, but decorators
    # are nicer if they don't have side-effects, so we return a new
    # function.
    def wrapped_view(*args, **kwargs):
        return view_func(*args, **kwargs)
    wrapped_view.csrf_exempt = True
    return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)

wrapped_view.csrf_exempt = True意思是取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件

然后将csrf_exempt函数中的内置函数wrapped_view赋值wrapped_view.csrf_exempt = True,使其拥有该属性,

# wraps函数

def wraps(wrapped,
          assigned = WRAPPER_ASSIGNMENTS,
          updated = WRAPPER_UPDATES):
    return partial(update_wrapper, wrapped=wrapped,
                   assigned=assigned, updated=updated)

wrapped是在def csrf_exempt(view_func):函数中的参数,也就是as_view的返回值

然后通过functools模块下的partial类进行装饰构造,partial 这个东西是针对函数起作用的,并且是部分的

# partial函数


    def __new__(*args, **keywords):
        if not args:
            raise TypeError("descriptor '__new__' of partial needs an argument")
        if len(args) < 2:
            raise TypeError("type 'partial' takes at least one argument")
        cls, func, *args = args
        if not callable(func):
            raise TypeError("the first argument must be callable")
        args = tuple(args)

        if hasattr(func, "func"):
            args = func.args + args
            tmpkw = func.keywords.copy()
            tmpkw.update(keywords)
            keywords = tmpkw
            del tmpkw
            func = func.func

        self = super(partial, cls).__new__(cls)

        self.func = func
        self.args = args
        self.keywords = keywords
        return self

    def __call__(*args, **keywords):
        if not args:
            raise TypeError("descriptor '__call__' of partial needs an argument")
        self, *args = args
        newkeywords = self.keywords.copy()
        newkeywords.update(keywords)
        return self.func(*self.args, *args, **newkeywords)

csrf_exempt函数中的wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)传入参数wrapper view, 通过对象可调用功能,进行调用__call__方法 .

APIView源码分析

原文:https://www.cnblogs.com/kp1995/p/10596569.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!