Separate permissions per methods
I am writing an API using Django REST Framework and I am wondering if can specify permissions per method when using class based views.
Reading the documentation I see that is quite easy to do if you are writing function based views, just using the @permission_classes
decorator over the function of the views you want to protect with permissions. However, I don't see a way to do the same when using CBVs with the APIView
class, because then I specify the permissions for the full class with the permission_classes
attribute, but that will be applied then to all class methods ( get
, post
, put
...).
So, is it possible to have the API views written with CBVs and also specify different permissions for each method of a view class?
Permissions are applied to the entire View class, but you can take into account aspects of the request (like the method such as GET or POST) in your authorization decision.
See the built-in IsAuthenticatedOrReadOnly
as an example:
SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']
class IsAuthenticatedOrReadOnly(BasePermission):
"""
The request is authenticated as a user, or is a read-only request.
"""
def has_permission(self, request, view):
if (request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated()):
return True
return False
I've come across the same problem when using CBV's, as i have fairly complex permissions logic depending on the request method.
The solution i came up with was to use the third party 'rest_condition' app listed at the bottom of this page
http://www.django-rest-framework.org/api-guide/permissions
https://github.com/caxap/rest_condition
I just split the permissions flow logic so that each branch will run, depending on the request method.
from rest_condition import And, Or, Not
class MyClassBasedView(APIView):
permission_classes = [Or(And(IsReadOnlyRequest, IsAllowedRetrieveThis, IsAllowedRetrieveThat),
And(IsPostRequest, IsAllowedToCreateThis, ...),
And(IsPutPatchRequest, ...),
And(IsDeleteRequest, ...)]
So the 'Or' determines which branch of the permissions should run depending on the request method and the 'And' wraps the permissions relating to the accepted request method, so all must pass for permission to be granted. You can also mix 'Or', 'And' and 'Not' within each flow to create even more complex permissions.
The permission classes to run each branch simply look like this,
class IsReadyOnlyRequest(permissions.BasePermission):
def has_permission(self, request, view):
return request.method in permissions.SAFE_METHODS
class IsPostRequest(permissions.BasePermission):
def has_permission(self, request, view):
return request.method == "POST"
... #You get the idea
链接地址: http://www.djcxy.com/p/69094.html
上一篇: 金字塔装饰者链接
下一篇: 每种方法分开的权限