I would like to manage my objects permission using django-guardian in a restful project (using django-rest-framework).
What I would like :
- Allow the connected user to create an object only if he have the "add_modelname" permission.
- When the connected user create an object, set the "delete_modelname" and "change_modelname" permission.
- Allow the connected user to edit an object only if he have the "change_modelobject" permission.
- Allow the connected user to delete an object only if he have the "delete_modelobject" permission.
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).