APIViewのpermission_classesはどんな仕組みで動いているのか
APIViewのプロパティは以下の通り。
# APIViewのプロパティ class APIView(View): # The following policies may be set at either globally, or per-view. renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES parser_classes = api_settings.DEFAULT_PARSER_CLASSES authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES #コイツ content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS metadata_class = api_settings.DEFAULT_METADATA_CLASS versioning_class = api_settings.DEFAULT_VERSIONING_CLASS # Allow dependency injection of other settings to make testing easier. settings = api_settings schema = DefaultSchema()
次にpermission_classesを使っているメソッドは何があるか??
それはget_permissionsだった。このメソッドはpermisson_classをインスタンス化したリストを作成する役割である。
# https://github.com/encode/django-rest-framework/blob/3db88778893579e1d7609b584ef35409c8aa5a22/rest_framework/views.py#L274 def get_permissions(self): """ Instantiates and returns the list of permissions that this view requires. """ return [permission() for permission in self.permission_classes]
じゃあ、このget_permissionsメソッドはどの文脈で使われているかということが次の疑問になる。
それは以下の通りcheck_permissionsとcheck_object_permissionsメソッドで使われていることが判明した。
def check_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(): if not permission.has_permission(request, self): self.permission_denied( request, message=getattr(permission, 'message', None), code=getattr(permission, 'code', None) ) def check_object_permissions(self, request, obj): """ Check if the request should be permitted for a given object. Raises an appropriate exception if the request is not permitted. """ for permission in self.get_permissions(): if not permission.has_object_permission(request, self, obj): self.permission_denied( request, message=getattr(permission, 'message', None), code=getattr(permission, 'code', None) )
こレラのメソッドはパーミッションがない場合にパーミッション拒否のメソッドが実行される。そういう意味で、permission.has_permission()メソッドがパーミッションのチェックとなっている。 このメソッドはpermissons.pyの各クラスメソッドに規定されている。