summaryrefslogtreecommitdiff
path: root/tests/inline_formsets
diff options
context:
space:
mode:
authorFlorian Apolloner <florian@apolloner.eu>2013-02-26 09:53:47 +0100
committerFlorian Apolloner <florian@apolloner.eu>2013-02-26 14:36:57 +0100
commit89f40e36246100df6a11316c31a76712ebc6c501 (patch)
tree6e65639683ddaf2027908d1ecb1739e0e2ff853b /tests/inline_formsets
parentb3d2ccb5bfbaf6e7fe1f98843baaa48c35a70950 (diff)
downloaddjango-89f40e36246100df6a11316c31a76712ebc6c501.tar.gz
Merged regressiontests and modeltests into the test root.
Diffstat (limited to 'tests/inline_formsets')
-rw-r--r--tests/inline_formsets/__init__.py0
-rw-r--r--tests/inline_formsets/models.py31
-rw-r--r--tests/inline_formsets/tests.py159
3 files changed, 190 insertions, 0 deletions
diff --git a/tests/inline_formsets/__init__.py b/tests/inline_formsets/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/inline_formsets/__init__.py
diff --git a/tests/inline_formsets/models.py b/tests/inline_formsets/models.py
new file mode 100644
index 0000000000..40c85fe739
--- /dev/null
+++ b/tests/inline_formsets/models.py
@@ -0,0 +1,31 @@
+# coding: utf-8
+from django.db import models
+from django.utils.encoding import python_2_unicode_compatible
+
+
+class School(models.Model):
+ name = models.CharField(max_length=100)
+
+class Parent(models.Model):
+ name = models.CharField(max_length=100)
+
+class Child(models.Model):
+ mother = models.ForeignKey(Parent, related_name='mothers_children')
+ father = models.ForeignKey(Parent, related_name='fathers_children')
+ school = models.ForeignKey(School)
+ name = models.CharField(max_length=100)
+
+@python_2_unicode_compatible
+class Poet(models.Model):
+ name = models.CharField(max_length=100)
+
+ def __str__(self):
+ return self.name
+
+@python_2_unicode_compatible
+class Poem(models.Model):
+ poet = models.ForeignKey(Poet)
+ name = models.CharField(max_length=100)
+
+ def __str__(self):
+ return self.name
diff --git a/tests/inline_formsets/tests.py b/tests/inline_formsets/tests.py
new file mode 100644
index 0000000000..e979fb4337
--- /dev/null
+++ b/tests/inline_formsets/tests.py
@@ -0,0 +1,159 @@
+from __future__ import absolute_import, unicode_literals
+
+from django.forms.models import inlineformset_factory
+from django.test import TestCase
+from django.utils import six
+
+from .models import Poet, Poem, School, Parent, Child
+
+
+class DeletionTests(TestCase):
+
+ def test_deletion(self):
+ PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True)
+ poet = Poet.objects.create(name='test')
+ poem = poet.poem_set.create(name='test poem')
+ data = {
+ 'poem_set-TOTAL_FORMS': '1',
+ 'poem_set-INITIAL_FORMS': '1',
+ 'poem_set-MAX_NUM_FORMS': '0',
+ 'poem_set-0-id': str(poem.pk),
+ 'poem_set-0-poet': str(poet.pk),
+ 'poem_set-0-name': 'test',
+ 'poem_set-0-DELETE': 'on',
+ }
+ formset = PoemFormSet(data, instance=poet)
+ formset.save()
+ self.assertTrue(formset.is_valid())
+ self.assertEqual(Poem.objects.count(), 0)
+
+ def test_add_form_deletion_when_invalid(self):
+ """
+ Make sure that an add form that is filled out, but marked for deletion
+ doesn't cause validation errors.
+ """
+ PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True)
+ poet = Poet.objects.create(name='test')
+ data = {
+ 'poem_set-TOTAL_FORMS': '1',
+ 'poem_set-INITIAL_FORMS': '0',
+ 'poem_set-MAX_NUM_FORMS': '0',
+ 'poem_set-0-id': '',
+ 'poem_set-0-poem': '1',
+ 'poem_set-0-name': 'x' * 1000,
+ }
+ formset = PoemFormSet(data, instance=poet)
+ # Make sure this form doesn't pass validation.
+ self.assertEqual(formset.is_valid(), False)
+ self.assertEqual(Poem.objects.count(), 0)
+
+ # Then make sure that it *does* pass validation and delete the object,
+ # even though the data isn't actually valid.
+ data['poem_set-0-DELETE'] = 'on'
+ formset = PoemFormSet(data, instance=poet)
+ self.assertEqual(formset.is_valid(), True)
+ formset.save()
+ self.assertEqual(Poem.objects.count(), 0)
+
+ def test_change_form_deletion_when_invalid(self):
+ """
+ Make sure that a change form that is filled out, but marked for deletion
+ doesn't cause validation errors.
+ """
+ PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True)
+ poet = Poet.objects.create(name='test')
+ poem = poet.poem_set.create(name='test poem')
+ data = {
+ 'poem_set-TOTAL_FORMS': '1',
+ 'poem_set-INITIAL_FORMS': '1',
+ 'poem_set-MAX_NUM_FORMS': '0',
+ 'poem_set-0-id': six.text_type(poem.id),
+ 'poem_set-0-poem': six.text_type(poem.id),
+ 'poem_set-0-name': 'x' * 1000,
+ }
+ formset = PoemFormSet(data, instance=poet)
+ # Make sure this form doesn't pass validation.
+ self.assertEqual(formset.is_valid(), False)
+ self.assertEqual(Poem.objects.count(), 1)
+
+ # Then make sure that it *does* pass validation and delete the object,
+ # even though the data isn't actually valid.
+ data['poem_set-0-DELETE'] = 'on'
+ formset = PoemFormSet(data, instance=poet)
+ self.assertEqual(formset.is_valid(), True)
+ formset.save()
+ self.assertEqual(Poem.objects.count(), 0)
+
+ def test_save_new(self):
+ """
+ Make sure inlineformsets respect commit=False
+ regression for #10750
+ """
+ # exclude some required field from the forms
+ ChildFormSet = inlineformset_factory(School, Child, exclude=['father', 'mother'])
+ school = School.objects.create(name='test')
+ mother = Parent.objects.create(name='mother')
+ father = Parent.objects.create(name='father')
+ data = {
+ 'child_set-TOTAL_FORMS': '1',
+ 'child_set-INITIAL_FORMS': '0',
+ 'child_set-MAX_NUM_FORMS': '0',
+ 'child_set-0-name': 'child',
+ }
+ formset = ChildFormSet(data, instance=school)
+ self.assertEqual(formset.is_valid(), True)
+ objects = formset.save(commit=False)
+ for obj in objects:
+ obj.mother = mother
+ obj.father = father
+ obj.save()
+ self.assertEqual(school.child_set.count(), 1)
+
+
+class InlineFormsetFactoryTest(TestCase):
+ def test_inline_formset_factory(self):
+ """
+ These should both work without a problem.
+ """
+ inlineformset_factory(Parent, Child, fk_name='mother')
+ inlineformset_factory(Parent, Child, fk_name='father')
+
+ def test_exception_on_unspecified_foreign_key(self):
+ """
+ Child has two ForeignKeys to Parent, so if we don't specify which one
+ to use for the inline formset, we should get an exception.
+ """
+ six.assertRaisesRegex(self, Exception,
+ "<class 'regressiontests.inline_formsets.models.Child'> has more than 1 ForeignKey to <class 'regressiontests.inline_formsets.models.Parent'>",
+ inlineformset_factory, Parent, Child
+ )
+
+ def test_fk_name_not_foreign_key_field_from_child(self):
+ """
+ If we specify fk_name, but it isn't a ForeignKey from the child model
+ to the parent model, we should get an exception.
+ """
+ self.assertRaises(Exception,
+ "fk_name 'school' is not a ForeignKey to <class 'regressiontests.inline_formsets.models.Parent'>",
+ inlineformset_factory, Parent, Child, fk_name='school'
+ )
+
+ def test_non_foreign_key_field(self):
+ """
+ If the field specified in fk_name is not a ForeignKey, we should get an
+ exception.
+ """
+ six.assertRaisesRegex(self, Exception,
+ "<class 'regressiontests.inline_formsets.models.Child'> has no field named 'test'",
+ inlineformset_factory, Parent, Child, fk_name='test'
+ )
+
+ def test_any_iterable_allowed_as_argument_to_exclude(self):
+ # Regression test for #9171.
+ inlineformset_factory(
+ Parent, Child, exclude=['school'], fk_name='mother'
+ )
+
+ inlineformset_factory(
+ Parent, Child, exclude=('school',), fk_name='mother'
+ )