定义:
判断用户是否拥有权限,有则放行,与django的中间件没有冲突,
只是对某个或某类用户定制专有的权限,可在中间件的基础上再加上某些判定.
源码流程:
1,所有函数进来首先走def dispatch函数.
def dispatch(self, request, *args, **kwargs): self.kwargs = kwargs request = self.initialize_request(request, *args, **kwargs) #封装request,返回Request self.request = request self.headers = self.default_response_headers ##返回头部 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) self.response = self.finalize_response(request, response, *args, **kwargs) return self.response
2,调用initial函数.
def initial(request, *args, **kwargs) self.format_kwarg = self.get_format_suffix(**kwargs) 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) #访问频率控制
3,执行self.check_permissions(request)
def check_permissions(self, request): for permission in self.get_permissions(): #实例化对象列表 if not permission.has_permission(request, self): self.permission_denied( request, message=getattr(permission, 'message', None) )
4,实例化对象列表self.get_permissions()
def get_permissions(self): return [permission() for permission in self.permission_classes]
5,从self.permission_classes拿值
class APIView(View): permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
6,执行api_settings
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
7,实例化APISettings,并且因为api_settings.DEFAULT_PERMISSION_CLASSES,
所以调用APISettings的__getattr__方法.
class APISettings(object): def __getattr__(self, attr): if attr not in self.defaults: raise AttributeError("Invalid API setting: '%s'" % attr) try: val = self.user_settings[attr] #user_settings在这里是None except KeyError: val = self.defaults[attr] #user_settings没有值所以调用这里. if attr in self.import_strings: val = perform_import(val, attr) # Cache the result self._cached_attrs.add(attr) #加到集合里,去重 setattr(self, attr, val) #设置 return val #
获取配置文件的所有信息,并返回给对象列表,等待遍历.
8,遍历对象列表并且判断是否返回False,如果是True则没有后续.
如果返回False则运行里面内容
if not permission.has_permission(request, self): self.permission_denied( request, message=getattr(permission, 'message', None) )
9,如果没有这个权限就执行里面的permission_denied,也就是报错的信息
self.permission_denied( request, message=getattr(permission, 'message', None) )
10,这里区别报错的信息,这里的错误信息可以通过前面传message重写信息
def permission_denied(self, request, message=None): #如果request.user有值 if request.authenticators and not request.successful_authenticator: raise exceptions.NotAuthenticated() # raise exceptions.PermissionDenied(detail=message)