mirror of
https://github.com/django/django.git
synced 2025-06-05 11:39:13 +00:00
[2.1.x] Fixed #29723 -- Fixed crash if InlineModelAdmin.has_add_permission() doesn't accept the obj argument.
* Refs #27991 -- Added testing for ModelAdmin.get_inline_instances() if the inline's has_add_permission() doesn't accept 'obj'. * Fixed #29723 -- Fixed crash if InlineModelAdmin.has_add_permission() doesn't accept the obj argument. Backport of fd8a7a5313f5e223212085b2e470e43c0047e066 from master
This commit is contained in:
parent
e7acd99113
commit
152b1d783b
@ -584,13 +584,8 @@ class ModelAdmin(BaseModelAdmin):
|
|||||||
inline_instances = []
|
inline_instances = []
|
||||||
for inline_class in self.inlines:
|
for inline_class in self.inlines:
|
||||||
inline = inline_class(self.model, self.admin_site)
|
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:
|
if request:
|
||||||
|
inline_has_add_permission = inline._has_add_permission(request, obj)
|
||||||
if not (inline.has_view_or_change_permission(request, obj) or
|
if not (inline.has_view_or_change_permission(request, obj) or
|
||||||
inline_has_add_permission or
|
inline_has_add_permission or
|
||||||
inline.has_delete_permission(request, obj)):
|
inline.has_delete_permission(request, obj)):
|
||||||
@ -1483,7 +1478,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||||||
for inline, formset in zip(inline_instances, formsets):
|
for inline, formset in zip(inline_instances, formsets):
|
||||||
fieldsets = list(inline.get_fieldsets(request, obj))
|
fieldsets = list(inline.get_fieldsets(request, obj))
|
||||||
readonly = list(inline.get_readonly_fields(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_change_permission = inline.has_change_permission(request, obj)
|
||||||
has_delete_permission = inline.has_delete_permission(request, obj)
|
has_delete_permission = inline.has_delete_permission(request, obj)
|
||||||
has_view_permission = inline.has_view_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)
|
js.append('collapse%s.js' % extra)
|
||||||
return forms.Media(js=['admin/js/%s' % url for url in js])
|
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):
|
def get_extra(self, request, obj=None, **kwargs):
|
||||||
"""Hook for customizing the number of extra inline forms."""
|
"""Hook for customizing the number of extra inline forms."""
|
||||||
return self.extra
|
return self.extra
|
||||||
@ -2046,7 +2046,7 @@ class InlineModelAdmin(BaseModelAdmin):
|
|||||||
|
|
||||||
base_model_form = defaults['form']
|
base_model_form = defaults['form']
|
||||||
can_change = self.has_change_permission(request, obj) if request else True
|
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):
|
class DeleteProtectedModelForm(base_model_form):
|
||||||
|
|
||||||
|
@ -46,3 +46,6 @@ Bugfixes
|
|||||||
``values_list()`` after combining querysets with ``extra()`` with
|
``values_list()`` after combining querysets with ``extra()`` with
|
||||||
``union()``, ``difference()``, or ``intersection()`` crashed due to
|
``union()``, ``difference()``, or ``intersection()`` crashed due to
|
||||||
mismatching columns (:ticket:`29694`).
|
mismatching columns (:ticket:`29694`).
|
||||||
|
|
||||||
|
* Fixed crash if ``InlineModelAdmin.has_add_permission()`` doesn't accept the
|
||||||
|
``obj`` argument (:ticket:`29723`).
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
from datetime import date
|
||||||
|
|
||||||
from django.contrib.admin.options import ModelAdmin, TabularInline
|
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 django.utils.deprecation import RemovedInDjango30Warning
|
||||||
|
|
||||||
from .models import Band, Song
|
from .models import Band, Song
|
||||||
@ -56,3 +60,45 @@ class HasAddPermissionObjTests(CheckTestCase):
|
|||||||
)
|
)
|
||||||
with self.assertWarnsMessage(RemovedInDjango30Warning, msg):
|
with self.assertWarnsMessage(RemovedInDjango30Warning, msg):
|
||||||
self.assertIsValid(BandAdmin, Band)
|
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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user