问题
I want to create permissions in Django Rest Framework, based on view + method + user permissions.
Is there a way to achieve this without manually writing each permission, and checking the permissions of the group that the user is in?
Also, another problem i am facing with, is that permission objects are tied up to a certain model. Since i have views that affect different models, or i want to grant different permissions on the method PUT, depending on what view i accessed (because it affects different fields), i want my permissions to be tied to a certain view, and not to a certain model.
Anyone know how this can be done?
I am looking for a solution in the sort of:
1) Create a Permissions object with the following parameters: View_affected, list_of_allowed_methods(GET,POST,etc.)
2) Create a Group object that has that permission associated
3) Add a user to the group
4) Have my default permission class take care of everything.
From what i have now, the step that is giving me problems is step1. Because i see no way of tying a Permission with a View, and because Permissions ask for a model, and i do not want a model.
Any help would be greatly appreciated!
回答1:
Well, the first step could be done easy with DRF. See http://www.django-rest-framework.org/api-guide/permissions#custom-permissions.
You must do something like that:
from functools import partial
from rest_framework import permissions
class MyPermission(permissions.BasePermission):
def __init__(self, allowed_methods):
super().__init__()
self.allowed_methods = allowed_methods
def has_permission(self, request, view):
return request.method in self.allowed_methods
class ExampleView(APIView):
permission_classes = (partial(MyPermission, ['GET', 'HEAD']),)
回答2:
Custom permission can be created in this way, more info in official documentation( https://www.django-rest-framework.org/api-guide/permissions/):
from rest_framework.permissions import BasePermission
# Custom permission for users with "is_active" = True.
class IsActive(BasePermission):
"""
Allows access only to "is_active" users.
"""
def has_permission(self, request, view):
return request.user and request.user.is_active
# Usage
from rest_framework.views import APIView
from rest_framework.response import Response
from .permissions import IsActive # Path to our custom permission
class ExampleView(APIView):
permission_classes = (IsActive,)
def get(self, request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
回答3:
thanks, I took this idea and got it to work like so:
class genericPermissionCheck(permissions.BasePermission):
def __init__(self, action, entity):
self.action = action
self.entity = entity
def has_permission(self, request, view):
print self.action
print self.entity
if request.user and request.user.role.access_rights.filter(action=self.action,entity=self.entity):
print 'permission granted'
return True
else:
return False
I used partial in the decorator for the categories action in my viewset class like so:
@list_route(methods=['get'],permission_classes=[partial(genericPermissionCheck,'Fetch','Categories')])
def Categories(self, request):
BTW, "access_rights" maps to an array of objects with a pair of action and object e.g. 'Edit' and 'Blog'
来源:https://stackoverflow.com/questions/23716855/django-rest-framework-custom-permissions-per-view