defas_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): defforce_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
defas_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__)) ifnot 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))
defdispatch(self, request, *args, **kwargs): """ `.dispatch()` is pretty much the same as Django's regular dispatch, but with extra hooks for startup, finalize, and exception handling. """ self.args = args self.kwargs = kwargs request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate?
try: self.initial(request, *args, **kwargs)
# Get the appropriate handler method 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
response = handler(request, *args, **kwargs)
except Exception as exc: response = self.handle_exception(exc)
defdispatch(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)
definitial(self, request, *args, **kwargs): """ Runs anything that needs to occur prior to calling the method handler. """ self.format_kwarg = self.get_format_suffix(**kwargs)
# Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg
# Determine the API version, if versioning is in use. version, scheme = self.determine_version(request, *args, **kwargs) # 版本 request.version, request.versioning_scheme = version, scheme
# Ensure that the incoming request is permitted self.perform_authentication(request) # 认证验证 self.check_permissions(request) # 权限验证 self.check_throttles(request) # 频率验证
defperform_authentication(self, request): """ Perform authentication on the incoming request. Note that if you override this and simply 'pass', then authentication will instead be performed lazily, the first time either `request.user` or `request.auth` is accessed. """ request.user
@property defuser(self): """ Returns the user associated with the current request, as authenticated by the authentication classes provided to the request. """ ifnot hasattr(self, '_user'): with wrap_attributeerrors(): self._authenticate() return self._user
def_authenticate(self): """ Attempt to authenticate the request using each authentication instance in turn. """ for authenticator in self.authenticators: # authenicators已经在initialize_request方法中给self定义过了 try: user_auth_tuple = authenticator.authenticate(self) # 执行认证类中的方法 认证 except exceptions.APIException: self._not_authenticated() # 报错就执行这个方法 raise
defget_authenticators(self): """ Instantiates and returns the list of authenticators that this view can use. """ return [auth() for auth in self.authentication_classes]
defcheck_permissions(self, request): """ Check if the request should be permitted. Raises an appropriate exception if the request is not permitted. """ for permission in self.get_permissions(): ifnot permission.has_permission(request, self): # has_permission 权限认证方法 # 如果到这里就是权限认证返回False 也就是没通过 self.permission_denied( # request, message=getattr(permission, 'message', None)
defget_permissions(self): """ Instantiates and returns the list of permissions that this view requires. """ return [permission() for permission in self.permission_classes]
classBasePermission(object): """ A base class from which all permission classes should inherit. """
defhas_permission(self, request, view): """ Return `True` if permission is granted, `False` otherwise. """ returnTrue
defhas_object_permission(self, request, view, obj): """ Return `True` if permission is granted, `False` otherwise. """ returnTrue
permission_denied
1 2 3 4 5 6 7
defpermission_denied(self, request, message=None): """ If request is not permitted, determine what kind of exception to raise. """ if request.authenticators andnot request.successful_authenticator: raise exceptions.NotAuthenticated() raise exceptions.PermissionDenied(detail=message)
defcheck_throttles(self, request): """ Check if request should be throttled. Raises an appropriate exception if the request is throttled. """ for throttle in self.get_throttles(): ifnot throttle.allow_request(request, self): self.throttled(request, throttle.wait())
""" Settings for REST framework are all namespaced in the REST_FRAMEWORK setting. For example your project's `settings.py` file might look like this: REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.TemplateHTMLRenderer', ) 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' ) } This module provides the `api_setting` object, that is used to access REST framework settings, checking for user settings first, then falling back to the defaults. """