1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Fixed #20522 - Allowed use of partially validated object in ModelAdmin.add_view formset validation.

Updated ModelAdmin to use form.instance when passing parent model to
child inlines for add_view. There is effectively no change in the
change_view since the previously passed 'obj' is the same as form.instance.

Thanks to meshy for report, and EvilDMP and timo for review.
This commit is contained in:
Jay Leadbetter
2013-11-14 19:26:19 -07:00
committed by Tim Graham
parent 1c7a83ee8e
commit c74504c2dd
5 changed files with 115 additions and 5 deletions

View File

@@ -51,7 +51,8 @@ from .models import (Article, BarAccount, CustomArticle, EmptyModel, FooAccount,
AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedCallable,
Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject,
Simple, UndeletableObject, UnchangeableObject, Choice, ShortMessage,
Telegram, Pizza, Topping, FilteredManager, City, Restaurant, Worker)
Telegram, Pizza, Topping, FilteredManager, City, Restaurant, Worker,
ParentWithDependentChildren)
from .admin import site, site2, CityAdmin
@@ -4597,7 +4598,7 @@ class TestLabelVisibility(TestCase):
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminViewOnSiteTest(TestCase):
class AdminViewOnSiteTests(TestCase):
urls = "admin_views.urls"
fixtures = ['admin-views-users.xml', 'admin-views-restaurants.xml']
@@ -4607,6 +4608,64 @@ class AdminViewOnSiteTest(TestCase):
def tearDown(self):
self.client.logout()
def test_add_view_form_and_formsets_run_validation(self):
"""
Issue #20522
Verifying that if the parent form fails validation, the inlines also
run validation even if validation is contingent on parent form data
"""
# The form validation should fail because 'some_required_info' is
# not included on the parent form, and the family_name of the parent
# does not match that of the child
post_data = {"family_name": "Test1",
"dependentchild_set-TOTAL_FORMS": "1",
"dependentchild_set-INITIAL_FORMS": "0",
"dependentchild_set-MAX_NUM_FORMS": "1",
"dependentchild_set-0-id": "",
"dependentchild_set-0-parent": "",
"dependentchild_set-0-family_name": "Test2"}
response = self.client.post('/test_admin/admin/admin_views/parentwithdependentchildren/add/',
post_data)
# just verifying the parent form failed validation, as expected --
# this isn't the regression test
self.assertTrue('some_required_info' in response.context['adminform'].form.errors)
# actual regression test
for error_set in response.context['inline_admin_formset'].formset.errors:
self.assertEqual(['Children must share a family name with their parents in this contrived test case'],
error_set.get('__all__'))
def test_change_view_form_and_formsets_run_validation(self):
"""
Issue #20522
Verifying that if the parent form fails validation, the inlines also
run validation even if validation is contingent on parent form data
"""
pwdc = ParentWithDependentChildren.objects.create(some_required_info=6,
family_name="Test1")
# The form validation should fail because 'some_required_info' is
# not included on the parent form, and the family_name of the parent
# does not match that of the child
post_data = {"family_name": "Test2",
"dependentchild_set-TOTAL_FORMS": "1",
"dependentchild_set-INITIAL_FORMS": "0",
"dependentchild_set-MAX_NUM_FORMS": "1",
"dependentchild_set-0-id": "",
"dependentchild_set-0-parent": str(pwdc.id),
"dependentchild_set-0-family_name": "Test1"}
response = self.client.post('/test_admin/admin/admin_views/parentwithdependentchildren/%d/'
% pwdc.id, post_data)
# just verifying the parent form failed validation, as expected --
# this isn't the regression test
self.assertTrue('some_required_info' in response.context['adminform'].form.errors)
# actual regression test
for error_set in response.context['inline_admin_formset'].formset.errors:
self.assertEqual(['Children must share a family name with their parents in this contrived test case'],
error_set.get('__all__'))
def test_validate(self):
"Ensure that the view_on_site value is either a boolean or a callable"
CityAdmin.view_on_site = True