From 01ee9c87b8c1c0e2edc19fcf0f17ce54ce0bdb6a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 4 Mar 2024 09:52:45 -0500 Subject: [PATCH] Update ObjectPermission.object_types to reference ObjectType --- netbox/netbox/tests/test_authentication.py | 12 ++--- netbox/netbox/tests/test_import.py | 6 +-- netbox/users/api/serializers.py | 4 +- netbox/users/forms/model_forms.py | 4 +- ...07_objectpermission_update_object_types.py | 19 ++++++++ netbox/users/models.py | 2 +- netbox/users/tests/test_api.py | 6 +-- netbox/users/tests/test_filtersets.py | 7 +-- netbox/utilities/permissions.py | 8 ++-- netbox/utilities/testing/api.py | 21 ++++----- netbox/utilities/testing/views.py | 45 ++++++++++--------- 11 files changed, 78 insertions(+), 56 deletions(-) create mode 100644 netbox/users/migrations/0007_objectpermission_update_object_types.py diff --git a/netbox/netbox/tests/test_authentication.py b/netbox/netbox/tests/test_authentication.py index 6a894edcd..6e049dcaf 100644 --- a/netbox/netbox/tests/test_authentication.py +++ b/netbox/netbox/tests/test_authentication.py @@ -2,13 +2,13 @@ import datetime from django.conf import settings from django.contrib.auth import get_user_model -from django.contrib.contenttypes.models import ContentType from django.test import Client from django.test.utils import override_settings from django.urls import reverse from netaddr import IPNetwork from rest_framework.test import APIClient +from core.models import ObjectType from dcim.models import Site from ipam.models import Prefix from users.models import Group, ObjectPermission, Token @@ -452,7 +452,7 @@ class ObjectPermissionAPIViewTestCase(TestCase): ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(Prefix)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(Prefix)) # Retrieve permitted object url = reverse('ipam-api:prefix-detail', @@ -482,7 +482,7 @@ class ObjectPermissionAPIViewTestCase(TestCase): ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(Prefix)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(Prefix)) # Retrieve all objects. Only permitted objects should be returned. response = self.client.get(url, **self.header) @@ -510,7 +510,7 @@ class ObjectPermissionAPIViewTestCase(TestCase): ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(Prefix)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(Prefix)) # Attempt to create a non-permitted object response = self.client.post(url, data, format='json', **self.header) @@ -541,7 +541,7 @@ class ObjectPermissionAPIViewTestCase(TestCase): ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(Prefix)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(Prefix)) # Attempt to edit a non-permitted object data = {'site': self.sites[0].pk} @@ -581,7 +581,7 @@ class ObjectPermissionAPIViewTestCase(TestCase): ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(Prefix)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(Prefix)) # Attempt to delete a non-permitted object url = reverse('ipam-api:prefix-detail', diff --git a/netbox/netbox/tests/test_import.py b/netbox/netbox/tests/test_import.py index bd07886e8..b0b21a07d 100644 --- a/netbox/netbox/tests/test_import.py +++ b/netbox/netbox/tests/test_import.py @@ -1,6 +1,6 @@ -from django.contrib.contenttypes.models import ContentType from django.test import override_settings +from core.models import ObjectType from dcim.models import * from users.models import ObjectPermission from utilities.choices import CSVDelimiterChoices, ImportFormatChoices @@ -67,7 +67,7 @@ class CSVImportTestCase(ModelViewTestCase): obj_perm = ObjectPermission(name='Test permission', actions=['add']) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with model-level permission self.assertHttpStatus(self.client.get(self._get_url('import')), 200) @@ -108,7 +108,7 @@ class CSVImportTestCase(ModelViewTestCase): obj_perm = ObjectPermission(name='Test permission', actions=['add']) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with model-level permission self.assertHttpStatus(self.client.get(self._get_url('import')), 200) diff --git a/netbox/users/api/serializers.py b/netbox/users/api/serializers.py index b9bd55e75..b99371b6c 100644 --- a/netbox/users/api/serializers.py +++ b/netbox/users/api/serializers.py @@ -1,12 +1,12 @@ from django.conf import settings from django.contrib.auth import authenticate from django.contrib.auth import get_user_model -from django.contrib.contenttypes.models import ContentType from drf_spectacular.utils import extend_schema_field from drf_spectacular.types import OpenApiTypes from rest_framework import serializers from rest_framework.exceptions import AuthenticationFailed, PermissionDenied +from core.models import ObjectType from netbox.api.fields import ContentTypeField, IPNetworkSerializer, SerializedPKRelatedField from netbox.api.serializers import ValidatedModelSerializer from users.models import Group, ObjectPermission, Token @@ -161,7 +161,7 @@ class TokenProvisionSerializer(TokenSerializer): class ObjectPermissionSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='users-api:objectpermission-detail') object_types = ContentTypeField( - queryset=ContentType.objects.all(), + queryset=ObjectType.objects.all(), many=True ) groups = SerializedPKRelatedField( diff --git a/netbox/users/forms/model_forms.py b/netbox/users/forms/model_forms.py index 2a024bf47..6c717d1ea 100644 --- a/netbox/users/forms/model_forms.py +++ b/netbox/users/forms/model_forms.py @@ -1,12 +1,12 @@ from django import forms from django.conf import settings from django.contrib.auth import get_user_model -from django.contrib.contenttypes.models import ContentType from django.contrib.postgres.forms import SimpleArrayField from django.core.exceptions import FieldError from django.utils.html import mark_safe from django.utils.translation import gettext_lazy as _ +from core.models import ObjectType from ipam.formfields import IPNetworkFormField from ipam.validators import prefix_validator from netbox.preferences import PREFERENCES @@ -278,7 +278,7 @@ class GroupForm(forms.ModelForm): class ObjectPermissionForm(forms.ModelForm): object_types = ContentTypeMultipleChoiceField( label=_('Object types'), - queryset=ContentType.objects.all(), + queryset=ObjectType.objects.all(), limit_choices_to=OBJECTPERMISSION_OBJECT_TYPES, widget=forms.SelectMultiple(attrs={'size': 6}) ) diff --git a/netbox/users/migrations/0007_objectpermission_update_object_types.py b/netbox/users/migrations/0007_objectpermission_update_object_types.py new file mode 100644 index 000000000..d3018a602 --- /dev/null +++ b/netbox/users/migrations/0007_objectpermission_update_object_types.py @@ -0,0 +1,19 @@ +# Generated by Django 5.0.1 on 2024-03-04 14:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0010_gfk_indexes'), + ('users', '0006_custom_group_model'), + ] + + operations = [ + migrations.AlterField( + model_name='objectpermission', + name='object_types', + field=models.ManyToManyField(limit_choices_to=models.Q(models.Q(models.Q(('app_label__in', ['account', 'admin', 'auth', 'contenttypes', 'sessions', 'taggit', 'users']), _negated=True), models.Q(('app_label', 'auth'), ('model__in', ['group', 'user'])), models.Q(('app_label', 'users'), ('model__in', ['objectpermission', 'token'])), _connector='OR')), related_name='object_permissions', to='core.objecttype'), + ), + ] diff --git a/netbox/users/models.py b/netbox/users/models.py index 94eb0ad58..d2ee16e5e 100644 --- a/netbox/users/models.py +++ b/netbox/users/models.py @@ -383,7 +383,7 @@ class ObjectPermission(models.Model): default=True ) object_types = models.ManyToManyField( - to='contenttypes.ContentType', + to='core.ObjectType', limit_choices_to=OBJECTPERMISSION_OBJECT_TYPES, related_name='object_permissions' ) diff --git a/netbox/users/tests/test_api.py b/netbox/users/tests/test_api.py index 51fc21c97..2ff3545a6 100644 --- a/netbox/users/tests/test_api.py +++ b/netbox/users/tests/test_api.py @@ -1,7 +1,7 @@ from django.contrib.auth import get_user_model -from django.contrib.contenttypes.models import ContentType from django.urls import reverse +from core.models import ObjectType from users.models import Group, ObjectPermission, Token from utilities.testing import APIViewTestCases, APITestCase, create_test_user from utilities.utils import deepmerge @@ -64,7 +64,7 @@ class UserTest(APIViewTestCases.APIViewTestCase): ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) user_credentials = { 'username': 'user1', @@ -261,7 +261,7 @@ class ObjectPermissionTest( ) User.objects.bulk_create(users) - object_type = ContentType.objects.get(app_label='dcim', model='device') + object_type = ObjectType.objects.get(app_label='dcim', model='device') for i in range(3): objectpermission = ObjectPermission( diff --git a/netbox/users/tests/test_filtersets.py b/netbox/users/tests/test_filtersets.py index 5d373628f..d42133d8d 100644 --- a/netbox/users/tests/test_filtersets.py +++ b/netbox/users/tests/test_filtersets.py @@ -5,6 +5,7 @@ from django.contrib.contenttypes.models import ContentType from django.test import TestCase from django.utils.timezone import make_aware +from core.models import ObjectType from users import filtersets from users.models import Group, ObjectPermission, Token from utilities.testing import BaseFilterSetTests @@ -151,9 +152,9 @@ class ObjectPermissionTestCase(TestCase, BaseFilterSetTests): User.objects.bulk_create(users) object_types = ( - ContentType.objects.get(app_label='dcim', model='site'), - ContentType.objects.get(app_label='dcim', model='rack'), - ContentType.objects.get(app_label='dcim', model='device'), + ObjectType.objects.get(app_label='dcim', model='site'), + ObjectType.objects.get(app_label='dcim', model='rack'), + ObjectType.objects.get(app_label='dcim', model='device'), ) permissions = ( diff --git a/netbox/utilities/permissions.py b/netbox/utilities/permissions.py index c72a72db7..f4b7061ee 100644 --- a/netbox/utilities/permissions.py +++ b/netbox/utilities/permissions.py @@ -1,5 +1,4 @@ from django.conf import settings -from django.contrib.contenttypes.models import ContentType from django.db.models import Q from django.utils.translation import gettext_lazy as _ @@ -50,13 +49,14 @@ def resolve_permission_ct(name): :param name: Permission name in the format ._ """ + from core.models import ObjectType app_label, action, model_name = resolve_permission(name) try: - content_type = ContentType.objects.get(app_label=app_label, model=model_name) - except ContentType.DoesNotExist: + object_type = ObjectType.objects.get(app_label=app_label, model=model_name) + except ObjectType.DoesNotExist: raise ValueError(_("Unknown app_label/model_name for {name}").format(name=name)) - return content_type, action + return object_type, action def permission_is_exempt(name): diff --git a/netbox/utilities/testing/api.py b/netbox/utilities/testing/api.py index 20c607906..f5e12246b 100644 --- a/netbox/utilities/testing/api.py +++ b/netbox/utilities/testing/api.py @@ -10,6 +10,7 @@ from graphene.types import Dynamic as GQLDynamic, List as GQLList, Union as GQLU from rest_framework import status from rest_framework.test import APIClient +from core.models import ObjectType from extras.choices import ObjectChangeActionChoices from extras.models import ObjectChange from users.models import ObjectPermission, Token @@ -109,7 +110,7 @@ class APIViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET to permitted object url = self._get_detail_url(instance1) @@ -183,7 +184,7 @@ class APIViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET to permitted objects response = self.client.get(self._get_list_url(), **self.header) @@ -224,7 +225,7 @@ class APIViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) initial_count = self._get_queryset().count() response = self.client.post(self._get_list_url(), self.create_data[0], format='json', **self.header) @@ -258,7 +259,7 @@ class APIViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) initial_count = self._get_queryset().count() response = self.client.post(self._get_list_url(), self.create_data, format='json', **self.header) @@ -309,7 +310,7 @@ class APIViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) response = self.client.patch(url, update_data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_200_OK) @@ -344,7 +345,7 @@ class APIViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) id_list = list(self._get_queryset().values_list('id', flat=True)[:3]) self.assertEqual(len(id_list), 3, "Insufficient number of objects to test bulk update") @@ -387,7 +388,7 @@ class APIViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) response = self.client.delete(url, **self.header) self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT) @@ -413,7 +414,7 @@ class APIViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Target the three most recently created objects to avoid triggering recursive deletions # (e.g. with MPTT objects) @@ -504,7 +505,7 @@ class APIViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) response = self.client.post(url, data={'query': query}, **self.header) self.assertHttpStatus(response, status.HTTP_200_OK) @@ -529,7 +530,7 @@ class APIViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) response = self.client.post(url, data={'query': query}, **self.header) self.assertHttpStatus(response, status.HTTP_200_OK) diff --git a/netbox/utilities/testing/views.py b/netbox/utilities/testing/views.py index daa44b905..7bc776b1e 100644 --- a/netbox/utilities/testing/views.py +++ b/netbox/utilities/testing/views.py @@ -8,6 +8,7 @@ from django.test import override_settings from django.urls import reverse from django.utils.translation import gettext as _ +from core.models import ObjectType from extras.choices import ObjectChangeActionChoices from extras.models import ObjectChange from netbox.models.features import ChangeLoggingMixin @@ -93,7 +94,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with model-level permission self.assertHttpStatus(self.client.get(instance.get_absolute_url()), 200) @@ -109,7 +110,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET to permitted object self.assertHttpStatus(self.client.get(instance1.get_absolute_url()), 200) @@ -161,7 +162,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with model-level permission self.assertHttpStatus(self.client.get(self._get_url('add')), 200) @@ -197,7 +198,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with object-level permission self.assertHttpStatus(self.client.get(self._get_url('add')), 200) @@ -260,7 +261,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with model-level permission self.assertHttpStatus(self.client.get(self._get_url('edit', instance)), 200) @@ -295,7 +296,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with a permitted object self.assertHttpStatus(self.client.get(self._get_url('edit', instance1)), 200) @@ -349,7 +350,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with model-level permission self.assertHttpStatus(self.client.get(self._get_url('delete', instance)), 200) @@ -384,7 +385,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with a permitted object self.assertHttpStatus(self.client.get(self._get_url('delete', instance1)), 200) @@ -442,7 +443,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with model-level permission self.assertHttpStatus(self.client.get(self._get_url('list')), 200) @@ -458,7 +459,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with object-level permission response = self.client.get(self._get_url('list')) @@ -477,7 +478,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Test default CSV export response = self.client.get(f'{url}?export') @@ -524,7 +525,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Bulk create objects response = self.client.post(**request) @@ -548,7 +549,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Attempt to make the request with unmet constraints self.assertHttpStatus(self.client.post(**request), 200) @@ -610,7 +611,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try GET with model-level permission self.assertHttpStatus(self.client.get(self._get_url('import')), 200) @@ -639,7 +640,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Test POST with permission self.assertHttpStatus(self.client.post(self._get_url('import'), data), 302) @@ -674,7 +675,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Attempt to import non-permitted objects self.assertHttpStatus(self.client.post(self._get_url('import'), data), 200) @@ -730,7 +731,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try POST with model-level permission self.assertHttpStatus(self.client.post(self._get_url('bulk_edit'), data), 302) @@ -761,7 +762,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Attempt to bulk edit permitted objects into a non-permitted state response = self.client.post(self._get_url('bulk_edit'), data) @@ -811,7 +812,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try POST with model-level permission self.assertHttpStatus(self.client.post(self._get_url('bulk_delete'), data), 302) @@ -833,7 +834,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Attempt to bulk delete non-permitted objects initial_count = self._get_queryset().count() @@ -891,7 +892,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Try POST with model-level permission self.assertHttpStatus(self.client.post(self._get_url('bulk_rename'), data), 302) @@ -916,7 +917,7 @@ class ViewTestCases: ) obj_perm.save() obj_perm.users.add(self.user) - obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) + obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model)) # Attempt to bulk edit permitted objects into a non-permitted state response = self.client.post(self._get_url('bulk_rename'), data)