summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/contrib/admin/options.py16
-rw-r--r--docs/releases/2.1.1.txt3
-rw-r--r--tests/modeladmin/test_has_add_permission_obj_deprecation.py46
3 files changed, 57 insertions, 8 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 474c4226f8..4175eca614 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -584,13 +584,8 @@ class ModelAdmin(BaseModelAdmin):
inline_instances = []
for inline_class in self.inlines:
inline = inline_class(self.model, self.admin_site)
- # RemovedInDjango30Warning: obj will be a required argument.
- args = get_func_args(inline.has_add_permission)
- if 'obj' in args:
- inline_has_add_permission = inline.has_add_permission(request, obj)
- else:
- inline_has_add_permission = inline.has_add_permission(request)
if request:
+ inline_has_add_permission = inline._has_add_permission(request, obj)
if not (inline.has_view_or_change_permission(request, obj) or
inline_has_add_permission or
inline.has_delete_permission(request, obj)):
@@ -1483,7 +1478,7 @@ class ModelAdmin(BaseModelAdmin):
for inline, formset in zip(inline_instances, formsets):
fieldsets = list(inline.get_fieldsets(request, obj))
readonly = list(inline.get_readonly_fields(request, obj))
- has_add_permission = inline.has_add_permission(request, obj)
+ has_add_permission = inline._has_add_permission(request, obj)
has_change_permission = inline.has_change_permission(request, obj)
has_delete_permission = inline.has_delete_permission(request, obj)
has_view_permission = inline.has_view_permission(request, obj)
@@ -2001,6 +1996,11 @@ class InlineModelAdmin(BaseModelAdmin):
js.append('collapse%s.js' % extra)
return forms.Media(js=['admin/js/%s' % url for url in js])
+ def _has_add_permission(self, request, obj):
+ # RemovedInDjango30Warning: obj will be a required argument.
+ args = get_func_args(self.has_add_permission)
+ return self.has_add_permission(request, obj) if 'obj' in args else self.has_add_permission(request)
+
def get_extra(self, request, obj=None, **kwargs):
"""Hook for customizing the number of extra inline forms."""
return self.extra
@@ -2046,7 +2046,7 @@ class InlineModelAdmin(BaseModelAdmin):
base_model_form = defaults['form']
can_change = self.has_change_permission(request, obj) if request else True
- can_add = self.has_add_permission(request, obj) if request else True
+ can_add = self._has_add_permission(request, obj) if request else True
class DeleteProtectedModelForm(base_model_form):
diff --git a/docs/releases/2.1.1.txt b/docs/releases/2.1.1.txt
index 759d24c391..821c90aa68 100644
--- a/docs/releases/2.1.1.txt
+++ b/docs/releases/2.1.1.txt
@@ -46,3 +46,6 @@ Bugfixes
``values_list()`` after combining querysets with ``extra()`` with
``union()``, ``difference()``, or ``intersection()`` crashed due to
mismatching columns (:ticket:`29694`).
+
+* Fixed crash if ``InlineModelAdmin.has_add_permission()`` doesn't accept the
+ ``obj`` argument (:ticket:`29723`).
diff --git a/tests/modeladmin/test_has_add_permission_obj_deprecation.py b/tests/modeladmin/test_has_add_permission_obj_deprecation.py
index 18448e94d7..f5489a41db 100644
--- a/tests/modeladmin/test_has_add_permission_obj_deprecation.py
+++ b/tests/modeladmin/test_has_add_permission_obj_deprecation.py
@@ -1,4 +1,8 @@
+from datetime import date
+
from django.contrib.admin.options import ModelAdmin, TabularInline
+from django.contrib.admin.sites import AdminSite
+from django.test import TestCase
from django.utils.deprecation import RemovedInDjango30Warning
from .models import Band, Song
@@ -56,3 +60,45 @@ class HasAddPermissionObjTests(CheckTestCase):
)
with self.assertWarnsMessage(RemovedInDjango30Warning, msg):
self.assertIsValid(BandAdmin, Band)
+
+
+class MockRequest:
+ method = 'POST'
+ FILES = {}
+ POST = {}
+
+
+class SongInline(TabularInline):
+ model = Song
+
+ def has_add_permission(self, request):
+ return True
+
+
+class BandAdmin(ModelAdmin):
+ inlines = [SongInline]
+
+
+class ModelAdminTests(TestCase):
+
+ def setUp(self):
+ self.band = Band.objects.create(name='The Doors', bio='', sign_date=date(1965, 1, 1))
+ self.song = Song.objects.create(name='test', band=self.band)
+ self.site = AdminSite()
+ self.request = MockRequest()
+ self.request.user = self.MockAddUser()
+ self.ma = BandAdmin(Band, self.site)
+
+ class MockAddUser:
+ def has_perm(self, perm):
+ return perm == 'modeladmin.add_band'
+
+ def test_get_inline_instances(self):
+ self.assertEqual(len(self.ma.get_inline_instances(self.request)), 1)
+
+ def test_get_inline_formsets(self):
+ formsets, inline_instances = self.ma._create_formsets(self.request, self.band, change=True)
+ self.assertEqual(len(self.ma.get_inline_formsets(self.request, formsets, inline_instances)), 1)
+
+ def test_get_formsets_with_inlines(self):
+ self.assertEqual(len(list(self.ma. get_formsets_with_inlines(self.request, self.band))), 1)