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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With