Reputation: 4110
I would like to manage my objects permission using django-guardian in a restful project (using django-rest-framework).
What I would like :
I'm trying to manage thoses cases with this code :
view.py
class ModelNameViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
Additionally we also provide an extra `highlight` action.
"""
queryset = ModelName.objects.all()
serializer_class = ModelNameSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly, ModelNamePermission)
def create(self, request, *args, **kwargs):
assign_perm("change_modelname", request.user, self)
assign_perm("delete_modelname", request.user, self)
return super().create(request, *args, **kwargs)
permissions.py
class ModelNamePermission(permissions.BasePermission):
"""
Custom permission to only allow owners of an object to edit it.
"""
def has_permission(self, request, view):
if request.method in ['GET']:
return request.user.has_perm('view_modelname')
if request.method in ['POST']:
return request.user.has_perm('add_modelname')
if request.method in ['PUT', 'PATCH']:
return request.user.has_perm('change_modelname')
if request.method in ['DELETE']:
return request.user.has_perm('delete_modelname')
return False
def has_object_permission(self, request, view, obj):
if request.method in ['GET']:
return request.user.has_perm('view_modelname', obj)
if request.method in ['POST']:
return request.user.has_perm('add_modelname', obj)
if request.method in ['PUT', 'PATCH']:
return request.user.has_perm('change_modelname', obj)
if request.method in ['DELETE']:
return request.user.has_perm('delete_modelname', obj)
return False
The first problem I encounter is that I have an error in this line :
assign_perm("change_modelname", request.user, self)
error :
error: 'ModelNameViewSet' object has no attribute '_meta'
And I think that the rest of the code will not works but at least you can see what I want to do.
I haven't seen any example with thoses specifics cases.
Edit : Another thing is that this code :
request.user.has_perm('view_coachingrequest')
allways returns true. But I've never set this permission to my user (only tried with admin user, maybe that's why).
Upvotes: 6
Views: 5612
Reputation: 96
The create
method of a viewset will return you a freshly created model instance. You are trying to assign the permission to the viewset object itself. The code for your create
method should be as follows:
def create(self, request, *args, **kwargs):
instance = super().create(request, *args, **kwargs)
assign_perm("change_modelname", request.user, instance)
assign_perm("delete_modelname", request.user, instance)
return instance
This will create the model instance and then assign your desired permissions to it before returning it.
Upvotes: 2