I'm using Django 2.1 and djangorestframework 3.9.2. I wish to be able to control access to REST operations on Django model objects via the Django admin interface, ideally using user permissions. For example, only users who have read permissions on model object Foo should be able to see Foo in my REST API.
I read the docs and it seems maybe I could use DjangoModelPermissions or DjangoObjectPermissions.
However, when I clear all user permissions in the DB, and set DEFAULT_PERMISSIONS_CLASS to either DjangoModelPermissions or DjangoObjectPermissions, I am still able to see things in the REST API. That means lack of permissions is not preventing me from seeing objects as I hoped.
Example settings:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.DjangoModelPermissions',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
}
An example object view:
from rest_framework import routers, serializers, viewsets
from .models import Example
class ExampleSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Example
fields = '__all__'
class ExampleViewSet(viewsets.ModelViewSet):
queryset = Example.objects.all()
serializer_class = ExampleSerializer
router = routers.DefaultRouter()
router.register(r'examples', ExampleViewSet)
Suggestions?
DjangoModelPermissions only enforce permission rules for data modification (for POST , PUT , PATCH and DELETE requests), but does not enforce permission rules for data viewing.
To restrict data viewing, you can add a custom view permisson, and subclass DjangoModelPermissions to use that permission, as explained in the docs
EDIT:
With Django 2.1, view model permission is added. So this will probably be supported by DjangoModelPermissions in the future releases, but until then, you can try subclassing DjangoModelPermissions like this to add check for view permissions:
class DjangoModelPermissionsWithRead(DjangoModelPermissions):
perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'],
'OPTIONS': [],
'HEAD': [],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}
EDIT 2: There is a feature request filed to support this.
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