Fixed #33111 -- Fixed passing object to ModelAdmin.get_inlines() when editing in admin change view.
ModelAdmin.get_inlines() should get an unmutated object when creating formsets during POST request.
This commit is contained in:
parent
1bb8200f2f
commit
2f0f30f973
|
@ -1585,12 +1585,16 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
)
|
)
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = ModelForm(request.POST, request.FILES, instance=obj)
|
form = ModelForm(request.POST, request.FILES, instance=obj)
|
||||||
|
formsets, inline_instances = self._create_formsets(
|
||||||
|
request,
|
||||||
|
form.instance if add else obj,
|
||||||
|
change=not add,
|
||||||
|
)
|
||||||
form_validated = form.is_valid()
|
form_validated = form.is_valid()
|
||||||
if form_validated:
|
if form_validated:
|
||||||
new_object = self.save_form(request, form, change=not add)
|
new_object = self.save_form(request, form, change=not add)
|
||||||
else:
|
else:
|
||||||
new_object = form.instance
|
new_object = form.instance
|
||||||
formsets, inline_instances = self._create_formsets(request, new_object, change=not add)
|
|
||||||
if all_valid(formsets) and form_validated:
|
if all_valid(formsets) and form_validated:
|
||||||
self.save_model(request, new_object, form, not add)
|
self.save_model(request, new_object, form, not add)
|
||||||
self.save_related(request, form, formsets, not add)
|
self.save_related(request, form, formsets, not add)
|
||||||
|
|
|
@ -11,8 +11,9 @@ from .models import (
|
||||||
Inner4Tabular, Inner5Stacked, Inner5Tabular, NonAutoPKBook,
|
Inner4Tabular, Inner5Stacked, Inner5Tabular, NonAutoPKBook,
|
||||||
NonAutoPKBookChild, Novel, NovelReadonlyChapter, OutfitItem,
|
NonAutoPKBookChild, Novel, NovelReadonlyChapter, OutfitItem,
|
||||||
ParentModelWithCustomPk, Person, Poll, Profile, ProfileCollection,
|
ParentModelWithCustomPk, Person, Poll, Profile, ProfileCollection,
|
||||||
Question, ReadOnlyInline, ShoppingWeakness, Sighting, SomeChildModel,
|
Question, ReadOnlyInline, ShoppingWeakness, ShowInlineChild,
|
||||||
SomeParentModel, SottoCapo, Teacher, Title, TitleCollection,
|
ShowInlineParent, Sighting, SomeChildModel, SomeParentModel, SottoCapo,
|
||||||
|
Teacher, Title, TitleCollection,
|
||||||
)
|
)
|
||||||
|
|
||||||
site = admin.AdminSite(name="admin")
|
site = admin.AdminSite(name="admin")
|
||||||
|
@ -371,6 +372,17 @@ class ChildHiddenFieldOnSingleLineStackedInline(admin.StackedInline):
|
||||||
fields = ('name', 'position')
|
fields = ('name', 'position')
|
||||||
|
|
||||||
|
|
||||||
|
class ShowInlineChildInline(admin.StackedInline):
|
||||||
|
model = ShowInlineChild
|
||||||
|
|
||||||
|
|
||||||
|
class ShowInlineParentAdmin(admin.ModelAdmin):
|
||||||
|
def get_inlines(self, request, obj):
|
||||||
|
if obj is not None and obj.show_inlines:
|
||||||
|
return [ShowInlineChildInline]
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
site.register(TitleCollection, inlines=[TitleInline])
|
site.register(TitleCollection, inlines=[TitleInline])
|
||||||
# Test bug #12561 and #12778
|
# Test bug #12561 and #12778
|
||||||
# only ModelAdmin media
|
# only ModelAdmin media
|
||||||
|
@ -402,6 +414,7 @@ site.register(Course, ClassAdminStackedHorizontal)
|
||||||
site.register(CourseProxy, ClassAdminStackedVertical)
|
site.register(CourseProxy, ClassAdminStackedVertical)
|
||||||
site.register(CourseProxy1, ClassAdminTabularVertical)
|
site.register(CourseProxy1, ClassAdminTabularVertical)
|
||||||
site.register(CourseProxy2, ClassAdminTabularHorizontal)
|
site.register(CourseProxy2, ClassAdminTabularHorizontal)
|
||||||
|
site.register(ShowInlineParent, ShowInlineParentAdmin)
|
||||||
# Used to test hidden fields in tabular and stacked inlines.
|
# Used to test hidden fields in tabular and stacked inlines.
|
||||||
site2 = admin.AdminSite(name='tabular_inline_hidden_field_admin')
|
site2 = admin.AdminSite(name='tabular_inline_hidden_field_admin')
|
||||||
site2.register(SomeParentModel, inlines=[ChildHiddenFieldTabularInline])
|
site2.register(SomeParentModel, inlines=[ChildHiddenFieldTabularInline])
|
||||||
|
|
|
@ -327,6 +327,12 @@ class CourseProxy2(Course):
|
||||||
|
|
||||||
|
|
||||||
# Other models
|
# Other models
|
||||||
|
class ShowInlineParent(models.Model):
|
||||||
|
show_inlines = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
|
||||||
|
class ShowInlineChild(models.Model):
|
||||||
|
parent = models.ForeignKey(ShowInlineParent, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
class ProfileCollection(models.Model):
|
class ProfileCollection(models.Model):
|
||||||
|
|
|
@ -12,8 +12,8 @@ from .models import (
|
||||||
ChildModel1, ChildModel2, Fashionista, FootNote, Holder, Holder2, Holder3,
|
ChildModel1, ChildModel2, Fashionista, FootNote, Holder, Holder2, Holder3,
|
||||||
Holder4, Inner, Inner2, Inner3, Inner4Stacked, Inner4Tabular, Novel,
|
Holder4, Inner, Inner2, Inner3, Inner4Stacked, Inner4Tabular, Novel,
|
||||||
OutfitItem, Parent, ParentModelWithCustomPk, Person, Poll, Profile,
|
OutfitItem, Parent, ParentModelWithCustomPk, Person, Poll, Profile,
|
||||||
ProfileCollection, Question, Sighting, SomeChildModel, SomeParentModel,
|
ProfileCollection, Question, ShowInlineParent, Sighting, SomeChildModel,
|
||||||
Teacher, VerboseNamePluralProfile, VerboseNameProfile,
|
SomeParentModel, Teacher, VerboseNamePluralProfile, VerboseNameProfile,
|
||||||
)
|
)
|
||||||
|
|
||||||
INLINE_CHANGELINK_HTML = 'class="inlinechangelink">Change</a>'
|
INLINE_CHANGELINK_HTML = 'class="inlinechangelink">Change</a>'
|
||||||
|
@ -618,6 +618,21 @@ class TestInline(TestDataMixin, TestCase):
|
||||||
self.assertContains(response, '<h2>Author</h2>', html=True) # Tabular.
|
self.assertContains(response, '<h2>Author</h2>', html=True) # Tabular.
|
||||||
self.assertContains(response, '<h2>Fashionista</h2>', html=True) # Stacked.
|
self.assertContains(response, '<h2>Fashionista</h2>', html=True) # Stacked.
|
||||||
|
|
||||||
|
def test_inlines_based_on_model_state(self):
|
||||||
|
parent = ShowInlineParent.objects.create(show_inlines=False)
|
||||||
|
data = {
|
||||||
|
'show_inlines': 'on',
|
||||||
|
'_save': 'Save',
|
||||||
|
}
|
||||||
|
change_url = reverse(
|
||||||
|
'admin:admin_inlines_showinlineparent_change',
|
||||||
|
args=(parent.id,),
|
||||||
|
)
|
||||||
|
response = self.client.post(change_url, data)
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
parent.refresh_from_db()
|
||||||
|
self.assertIs(parent.show_inlines, True)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='admin_inlines.urls')
|
@override_settings(ROOT_URLCONF='admin_inlines.urls')
|
||||||
class TestInlineMedia(TestDataMixin, TestCase):
|
class TestInlineMedia(TestDataMixin, TestCase):
|
||||||
|
|
Loading…
Reference in New Issue