zoukankan      html  css  js  c++  java
  • django 类通用视图详解

    view() :

        该类为所有类视图的父类,处于最底层,仅仅只对请求参数做校验后,给特定请求方法做特定调用。

         

        用法:

        url中定位到类方法:Aa.as_view() ——> View.as_view()方法对请求参数做判断后,转到View.dispatch() ——> 找到Aa.get() 或者Aa.post() 或者Aa.其他请求方法 ———>处理完成后返回view()

        需要对请求方式做特定处理,可以自行修改dispatch()方法。

     

        源码:

    class View(object):
        """
        Intentionally simple parent class for all views. Only implements
        dispatch-by-method and simple sanity checking.
          该视图为所有类视图的父类,处于最底层,仅仅只实现了给特定的请求方式
          进行特定方法的调度
        """
          # http 所有请求方式的列表
        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
        def __init__(self, **kwargs):
            """
            Constructor. Called in the URLconf; can contain helpful extra
            keyword arguments, and other things.
                # 构造函数接收键值对参数,该参数来源于 URLconf配置中的传递
            """
            # Go through keyword arguments, and either save their values to our
            # instance, or raise an error.
                # 接收关键字参数,并将其添加到实例中或者引发错误
            for key, value in six.iteritems(kwargs):
                setattr(self, key, value)
        @classonlymethod
        def as_view(cls, **initkwargs):
            """
                # as_view 是一个闭包,做了一些校验工作后,再返回view函数
            Main entry point for a request-response process.
            """
            for key in initkwargs:
                      #as_view()方法中,如果传递的关键字参数key为默认的http 请求方法,则报错,
                      #默认不允许使用http请求方法作为参数
                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__))
                      # as_view()方法中,如果传递过来的参数key 不在as_view()的属性中,也报错
                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))
                # view 方法作用是给请求对象添加三个参数,调用dispatch方法处理请求
            def view(request, *args, **kwargs): # 作用:增加属性,调用dispatch方法
                self = cls(**initkwargs) # 调用as_view 父类,创建一个实例对象
                      # 如果对象中有get属性,或者没有head属性,就创建head属性
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                      # 为对象创建request、args和kwargs 三个属性
                self.request = request
                self.args = args
                self.kwargs = kwargs
                      #调用dispatch 函数找到指定的请求方法,
                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
          # 找到请求的方法,执行该方法
        def dispatch(self, request, *args, **kwargs):
            # Try to dispatch to the right method; if a method doesn't exist,
            # defer to the error handler. Also defer to the error handler if the
            # request method isn't on the approved list.
                # 找到请求的方法,如果请求方法不在允许的列表中或者请求方法不存在就按照错误处理
                # http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
                # 如果请求方法存在,则取出该方法
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
                # 如果不存在则报405错误
            else:
                handler = self.http_method_not_allowed
                # 执行该请求方法
            return handler(request, *args, **kwargs)
        def http_method_not_allowed(self, request, *args, **kwargs):
            logger.warning(
                'Method Not Allowed (%s): %s', request.method, request.path,
                extra={'status_code': 405, 'request': request}
            )
            return http.HttpResponseNotAllowed(self._allowed_methods())
        def options(self, request, *args, **kwargs):
            """
            Handles responding to requests for the OPTIONS HTTP verb.
            """
            response = http.HttpResponse()
            response['Allow'] = ', '.join(self._allowed_methods())
            response['Content-Length'] = '0'
            return response
        def _allowed_methods(self):
            return [m.upper() for m in self.http_method_names if hasattr(self, m)]
    

       用法实例: 

    class LoginUserView(View):
       def dispatch(self, request, *args, **kwargs):
          print "进入了改写后的dispatch方法"
          discontext = super(LoginUserView, self).dispatch(request, *args, **kwargs)
          print "没有改变调用请求方式,直接返回原始dispatch调用"
          return discontext
       def post(self, request):
          context = userservice.login_user(request=request)
          return JsonResponse(context)
    

      

    image.png

    ListView() :

        

  • 相关阅读:
    CSRF的防御解决过程
    Spring生态研习【三】:Spring-kafka
    Spring生态研习【二】:SpEL(Spring Expression Language)
    Spring生态研习【一】:定时任务Spring-task
    给定一个大的任务,需要在考虑性能的情况下,快速处理完,并报告结果
    给定一个大于2的偶数,将其分解为两个质数的和
    一个求解平方根的算法题
    Kafka研究【一】:bring up环境
    LB+nginx+tomcat7集群模式下的https请求重定向(redirect)后变成http的解决方案
    IDEA使用笔记(八)——自动生成 serialVersionUID 的设置
  • 原文地址:https://www.cnblogs.com/cpy-devops/p/10368382.html
Copyright © 2011-2022 走看看