Respect can_read_model in DjangoModelPermissions

Django version 2.1 introduced the `can_read_model` permission
to support read-only ModelAdmin views. Add support for this
permission to a DjangoModelPermissions subclass.

(A subclass is created in order to preserve
backwards-compatibility with versions of Django that don't
support this flag).
This commit is contained in:
Paul Tiplady 2018-11-18 12:28:13 -08:00
parent 2084555fbe
commit b085754aa1
2 changed files with 15 additions and 2 deletions

View File

@ -151,7 +151,7 @@ class DjangoModelPermissions(BasePermission):
# Override this if you need to also provide 'view' permissions, # Override this if you need to also provide 'view' permissions,
# or if you want to provide custom permission codes. # or if you want to provide custom permission codes.
perms_map = { perms_map = {
'GET': [], 'GET': ['%(app_label)s.view_%(model_name)s'],
'OPTIONS': [], 'OPTIONS': [],
'HEAD': [], 'HEAD': [],
'POST': ['%(app_label)s.add_%(model_name)s'], 'POST': ['%(app_label)s.add_%(model_name)s'],

View File

@ -79,7 +79,8 @@ class ModelPermissionsIntegrationTests(TestCase):
user.user_permissions.set([ user.user_permissions.set([
Permission.objects.get(codename='add_basicmodel'), Permission.objects.get(codename='add_basicmodel'),
Permission.objects.get(codename='change_basicmodel'), Permission.objects.get(codename='change_basicmodel'),
Permission.objects.get(codename='delete_basicmodel') Permission.objects.get(codename='delete_basicmodel'),
Permission.objects.get(codename='view_basicmodel'),
]) ])
user = User.objects.create_user('updateonly', 'updateonly@example.com', 'password') user = User.objects.create_user('updateonly', 'updateonly@example.com', 'password')
@ -117,6 +118,12 @@ class ModelPermissionsIntegrationTests(TestCase):
response = get_queryset_list_view(request, pk=1) response = get_queryset_list_view(request, pk=1)
self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(response.status_code, status.HTTP_201_CREATED)
def test_has_read_permissions(self):
request = factory.get('/', {'text': 'foobar'}, format='json',
HTTP_AUTHORIZATION=self.permitted_credentials)
response = root_view(request, pk=1)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_has_put_permissions(self): def test_has_put_permissions(self):
request = factory.put('/1', {'text': 'foobar'}, format='json', request = factory.put('/1', {'text': 'foobar'}, format='json',
HTTP_AUTHORIZATION=self.permitted_credentials) HTTP_AUTHORIZATION=self.permitted_credentials)
@ -134,6 +141,12 @@ class ModelPermissionsIntegrationTests(TestCase):
response = root_view(request, pk=1) response = root_view(request, pk=1)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_does_not_have_read_permissions(self):
request = factory.get('/', {'text': 'foobar'}, format='json',
HTTP_AUTHORIZATION=self.disallowed_credentials)
response = root_view(request, pk=1)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_does_not_have_put_permissions(self): def test_does_not_have_put_permissions(self):
request = factory.put('/1', {'text': 'foobar'}, format='json', request = factory.put('/1', {'text': 'foobar'}, format='json',
HTTP_AUTHORIZATION=self.disallowed_credentials) HTTP_AUTHORIZATION=self.disallowed_credentials)