Django rest framework 소스 읽기 (2)----CBV 모드

12757 단어 Django 소스 읽기
CBV 반사 기반 구현 요청 방식에 따라 다른 방법 실행
  • CBV 클래스는restfranework에서 제공하는 APIView를 계승해야 하고, APIView는Django의views를 계승해야 한다.generic.base.View, 그래서 CBV는 Django의 View를 계승한다.Django에 요청하면 Django 중간부품의 방법을 실행한 다음에 루트 매칭을 진행합니다. 루트 매칭이 완료되면 CBV 클래스의 as 를 실행합니다.view 방법, CBV에 as 가 정의되어 있지 않음view 메서드, 대신 Django의 View 클래스에서 as 실행view 방법.
  • View 클래스는 as클래스 방법, 주의하십시오. 이 방법은 클래스 방법으로만 사용할 수 있으며, 실례에 사용할 수 없습니다. 이것은 내부 방법인view () 를 되돌려줍니다. 이 방법에서 하는 일은 디스패치의 일입니다. 요청한 방법에 따라 요청을 처리하는 방법을 사용합니다. GET 요청을 보내면view () 방법에서 get () 방법으로 나누어 처리합니다.View류는 주로 이 기능을 봉인했다. 이 기능은 최고층의 추상적인 기능이고 모든view는 이 특성을 필요로 한다.
  • class View:
        """
        Intentionally simple parent class for all views. Only implements
        dispatch-by-method and simple sanity checking.
        """
    
        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.
            """
            # Go through keyword arguments, and either save their values to our
            # instance, or raise an error.
            for key, value in kwargs.items():
                setattr(self, key, value)
    
        @classonlymethod
        def as_view(cls, **initkwargs):
            """Main entry point for a request-response process."""
            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.setup(request, *args, **kwargs)
                if not hasattr(self, 'request'):
                    raise AttributeError(
                        "%s instance has no 'request' attribute. Did you override "
                        "setup() and forget to call super()?" % cls.__name__
                    )
                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
    
  • :
  • View의 원본에서 볼 수 있듯이 View류에서 http 요청의 8가지 방법http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']이 as 에서 먼저 정의되었다.view 방법에서 판단을 하는데 요청한 방법이 http_method_names에 없으면 이상을 던집니다.
  • 여기의cls는 실제적으로 사용자 정의 CBV류를 가리킨다. 이어서 asview 방법에서view 방법을 정의하고view 방법에서CBV류를 실례화(self = cls(**initkwargs))하여self 대상을 얻는다.
  • 그리고 self 대상에서 브라우저가 보낸 Request 요청을 봉인하고 마지막으로 self 대상의 디스패치 방법을 호출하여 디스패치 방법의 값을 되돌려 Request를 처리합니다.
  • self 대상은 CBV를 실례화한 것이기 때문에 사용자 정의 CBV 클래스의 디스패치 방법을 먼저 실행합니다.CBV 클래스에 dispatch 메서드가 정의되어 있지 않으면 Django의 View에서 dispatch 메서드를 실행합니다.

  •     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.
            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
            return handler(request, *args, **kwargs)
    
  • :
  • 디스패치 방법에서 Request.method에서 소문자로 변환하여 정의된 httpmethod_names에서 만약 Request.method는 http 에 존재합니다.method_names에서는 getattr가 반사되는 방식으로handler를 얻을 수 있습니다.
  • 여기 디스패치 방법에서self는 사용자 정의 CBV 클래스를 실례화한 대상을 가리킨다.
  • CBV 클래스에서 Request를 가져옵니다.method에 대응하는 방법은 CBV의 방법을 실행하고 되돌려줍니다. Django 프로젝트에서 CBV 모드를 사용하면 클래스의 요청 방법에 대응하는 함수를 가져오는 getattr 방식을 실제적으로 호출할 수 있습니다.

  • 좋은 웹페이지 즐겨찾기