Skip to content

Commit

Permalink
Fix possible ManagementFormError on save after ValidationError
Browse files Browse the repository at this point in the history
fixes #164
  • Loading branch information
fdintino committed Mar 29, 2020
1 parent 073c215 commit e260b7b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
8 changes: 4 additions & 4 deletions nested_admin/nested.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,17 +288,17 @@ def _create_formsets(self, request, obj, change):
while i < len(nested_formsets_and_inline_instances):
formset, inline = nested_formsets_and_inline_instances[i]
i += 1
formset_forms = list(formset.forms)
if request.method == 'GET':
formset_forms += [None]
formset_forms = list(formset.forms) + [None]
for form in formset_forms:
if form is not None:
form.parent_formset = formset
form_prefix = form.prefix
form_obj = form.instance
is_empty_form = False
else:
form_prefix = formset.add_prefix('empty')
form_obj = None
is_empty_form = True
InlineFormSet = inline.get_formset(request, form_obj)

prefix = '%s-%s' % (form_prefix, InlineFormSet.get_default_prefix())
Expand All @@ -319,7 +319,7 @@ def _create_formsets(self, request, obj, change):
'prefix': prefix,
'queryset': inline.get_queryset(request),
}
if request.method == 'POST':
if request.method == 'POST' and not is_empty_form:
formset_params.update({
'data': request.POST.copy(),
'files': request.FILES,
Expand Down
11 changes: 9 additions & 2 deletions nested_admin/tests/nested_polymorphic/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class BaseNestedPolymorphicTestCase(BaseNestedAdminTestCase):

@classmethod
def setUpClass(cls):
if django.VERSION > (2, 2):
if django.VERSION >= (3, 0):
raise SkipTest(
'django-polymorphic not yet compatible with Django 2.2 and 3.0')
'django-polymorphic not yet compatible with Django 3.0')
super(BaseNestedPolymorphicTestCase, cls).setUpClass()

def get_inline_model_names(self):
Expand Down Expand Up @@ -237,6 +237,13 @@ def add_inline(self, indexes=None, model=None, **kwargs):
self.set_field(field_name, val, indexes=indexes)
return indexes

def remove_inline(self, indexes):
item = self.get_item(indexes)
remove_handler = self.selenium.execute_script(
"return $(arguments[0]).nearest('.djn-remove-handler')[0]",
item)
self.click(remove_handler)

def get_num_inlines(self, indexes=None):
group = self.get_group(indexes=indexes)
group_id = group.get_attribute('id')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import time
from unittest import SkipTest
from django.test import TestCase

from .models import (
# ALevelTwoC, LevelTwoC, LevelTwoD, ALevelTwo, BLevelTwo, LevelTwoC,
LevelOneA, ALevelTwoD, TopLevel, LevelOne, LevelOneB,
LevelOneA, ALevelTwoC, ALevelTwoD, TopLevel, LevelOne, LevelOneB,
LevelTwo, BLevelTwoC, BLevelTwoD, GFKX)


Expand Down Expand Up @@ -62,6 +61,41 @@ def test_add_level_two_to_empty(self):
self.assertEqual(b_children[0].name, 'y')
self.assertEqual(b_children[0].bc, 'bcy')

def test_add_level_two_to_empty_with_validation_error(self):
obj = self.root_model.objects.create(name='test')
self.load_admin(obj)

l1_indexes_a = self.add_inline(model=LevelOneA, name='k', a='ak')
l2_indexes_a = self.add_inline(l1_indexes_a, model=ALevelTwoC, name='l')
self.save_form()

self.remove_inline(l2_indexes_a)

l1_indexes_b = self.add_inline(model=LevelOneB, name='m', b='bm')
self.add_inline(l1_indexes_b, model=BLevelTwoD, name='n', bd='bdn')
self.save_form()

children = obj.children.all()
self.assertEqual(len(children), 2)

a, b = list(children)

self.assertIsInstance(a, LevelOneA)
self.assertIsInstance(b, LevelOneB)

self.assertEqual(a.name, 'k')
self.assertEqual(a.a, 'ak')
self.assertEqual(len(a.a_set.all()), 0)

self.assertEqual(b.name, 'm')
self.assertEqual(b.b, 'bm')

b_children = b.b_set.all()
self.assertEqual(len(b_children), 1)
self.assertIsInstance(b_children[0], BLevelTwoD)
self.assertEqual(b_children[0].name, 'n')
self.assertEqual(b_children[0].bd, 'bdn')

def test_add_level_two_to_empty_drag_and_drop(self):
obj = self.root_model.objects.create(name='test')
self.load_admin(obj)
Expand Down

0 comments on commit e260b7b

Please sign in to comment.