diff options
| author | Tim Graham <timograham@gmail.com> | 2017-12-28 17:17:47 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-12-28 17:17:47 -0500 |
| commit | 46d1af2e82c2b2a6976397719afde33b5cff2498 (patch) | |
| tree | 9a3ef3e0590bcf4846ef3e385001f3b57695a657 /tests/generic_relations | |
| parent | 83a36ac49a98d5d8801ed8428612e9a56aeb8699 (diff) | |
Moved generic_inlineformset_factory() tests to a separate file.
Diffstat (limited to 'tests/generic_relations')
| -rw-r--r-- | tests/generic_relations/test_forms.py | 202 | ||||
| -rw-r--r-- | tests/generic_relations/tests.py | 180 |
2 files changed, 203 insertions, 179 deletions
diff --git a/tests/generic_relations/test_forms.py b/tests/generic_relations/test_forms.py new file mode 100644 index 0000000000..bed31034be --- /dev/null +++ b/tests/generic_relations/test_forms.py @@ -0,0 +1,202 @@ +from django import forms +from django.contrib.contenttypes.forms import generic_inlineformset_factory +from django.contrib.contenttypes.models import ContentType +from django.db import models +from django.test import TestCase +from django.test.utils import isolate_apps + +from .models import ( + Animal, ForProxyModelModel, Gecko, Mineral, ProxyRelatedModel, TaggedItem, +) + + +class CustomWidget(forms.TextInput): + pass + + +class TaggedItemForm(forms.ModelForm): + class Meta: + model = TaggedItem + fields = '__all__' + widgets = {'tag': CustomWidget} + + +class GenericInlineFormsetTests(TestCase): + + def test_output(self): + GenericFormSet = generic_inlineformset_factory(TaggedItem, extra=1) + formset = GenericFormSet() + self.assertHTMLEqual( + ''.join(form.as_p() for form in formset.forms), + """<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag"> +Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" +name="generic_relations-taggeditem-content_type-object_id-0-tag" maxlength="50" /></p> +<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> +<input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" +id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /> +<input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" +id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p>""" + ) + formset = GenericFormSet(instance=Animal()) + self.assertHTMLEqual( + ''.join(form.as_p() for form in formset.forms), + """<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag"> +Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" +type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" maxlength="50" /></p> +<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> +<input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" +id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /><input type="hidden" +name="generic_relations-taggeditem-content_type-object_id-0-id" +id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p>""" + ) + platypus = Animal.objects.create( + common_name='Platypus', latin_name='Ornithorhynchus anatinus', + ) + platypus.tags.create(tag='shiny') + GenericFormSet = generic_inlineformset_factory(TaggedItem, extra=1) + formset = GenericFormSet(instance=platypus) + tagged_item_id = TaggedItem.objects.get(tag='shiny', object_id=platypus.id).id + self.assertHTMLEqual( + ''.join(form.as_p() for form in formset.forms), + """<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> +<input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" +name="generic_relations-taggeditem-content_type-object_id-0-tag" value="shiny" maxlength="50" /></p> +<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> +<input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" +id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /> +<input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" +value="%s" id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p> +<p><label for="id_generic_relations-taggeditem-content_type-object_id-1-tag">Tag:</label> +<input id="id_generic_relations-taggeditem-content_type-object_id-1-tag" type="text" +name="generic_relations-taggeditem-content_type-object_id-1-tag" maxlength="50" /></p> +<p><label for="id_generic_relations-taggeditem-content_type-object_id-1-DELETE">Delete:</label> +<input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-1-DELETE" +id="id_generic_relations-taggeditem-content_type-object_id-1-DELETE" /> +<input type="hidden" name="generic_relations-taggeditem-content_type-object_id-1-id" +id="id_generic_relations-taggeditem-content_type-object_id-1-id" /></p>""" % tagged_item_id + ) + lion = Animal.objects.create(common_name='Lion', latin_name='Panthera leo') + formset = GenericFormSet(instance=lion, prefix='x') + self.assertHTMLEqual( + ''.join(form.as_p() for form in formset.forms), + """<p><label for="id_x-0-tag">Tag:</label> +<input id="id_x-0-tag" type="text" name="x-0-tag" maxlength="50" /></p> +<p><label for="id_x-0-DELETE">Delete:</label> <input type="checkbox" name="x-0-DELETE" id="id_x-0-DELETE" /> +<input type="hidden" name="x-0-id" id="id_x-0-id" /></p>""" + ) + + def test_options(self): + TaggedItemFormSet = generic_inlineformset_factory( + TaggedItem, + can_delete=False, + exclude=['tag'], + extra=3, + ) + platypus = Animal.objects.create(common_name='Platypus', latin_name='Ornithorhynchus anatinus') + harmless = platypus.tags.create(tag='harmless') + mammal = platypus.tags.create(tag='mammal') + # Works without a queryset. + formset = TaggedItemFormSet(instance=platypus) + self.assertEqual(len(formset.forms), 5) + self.assertHTMLEqual( + formset.forms[0].as_p(), + '<input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" value="%s" ' + 'id="id_generic_relations-taggeditem-content_type-object_id-0-id" />' % harmless.pk + ) + self.assertEqual(formset.forms[0].instance, harmless) + self.assertEqual(formset.forms[1].instance, mammal) + self.assertIsNone(formset.forms[2].instance.pk) + # A queryset can be used to alter display ordering. + formset = TaggedItemFormSet(instance=platypus, queryset=TaggedItem.objects.order_by('-tag')) + self.assertEqual(len(formset.forms), 5) + self.assertEqual(formset.forms[0].instance, mammal) + self.assertEqual(formset.forms[1].instance, harmless) + self.assertIsNone(formset.forms[2].instance.pk) + # A queryset that omits items. + formset = TaggedItemFormSet(instance=platypus, queryset=TaggedItem.objects.filter(tag__startswith='harm')) + self.assertEqual(len(formset.forms), 4) + self.assertEqual(formset.forms[0].instance, harmless) + self.assertIsNone(formset.forms[1].instance.pk) + + def test_get_queryset_ordering(self): + """ + BaseGenericInlineFormSet.get_queryset() adds default ordering, if + needed. + """ + inline_formset = generic_inlineformset_factory(TaggedItem, exclude=('tag',)) + formset = inline_formset(instance=Gecko.objects.create()) + self.assertIs(formset.get_queryset().ordered, True) + + def test_initial(self): + quartz = Mineral.objects.create(name='Quartz', hardness=7) + GenericFormSet = generic_inlineformset_factory(TaggedItem, extra=1) + ctype = ContentType.objects.get_for_model(quartz) + initial_data = [{ + 'tag': 'lizard', + 'content_type': ctype.pk, + 'object_id': quartz.pk, + }] + formset = GenericFormSet(initial=initial_data) + self.assertEqual(formset.forms[0].initial, initial_data[0]) + + def test_meta_widgets(self): + """TaggedItemForm has a widget defined in Meta.""" + Formset = generic_inlineformset_factory(TaggedItem, TaggedItemForm) + form = Formset().forms[0] + self.assertIsInstance(form['tag'].field.widget, CustomWidget) + + @isolate_apps('generic_relations') + def test_incorrect_content_type(self): + class BadModel(models.Model): + content_type = models.PositiveIntegerField() + + msg = "fk_name 'generic_relations.BadModel.content_type' is not a ForeignKey to ContentType" + with self.assertRaisesMessage(Exception, msg): + generic_inlineformset_factory(BadModel, TaggedItemForm) + + def test_save_new_uses_form_save(self): + class SaveTestForm(forms.ModelForm): + def save(self, *args, **kwargs): + self.instance.saved_by = 'custom method' + return super().save(*args, **kwargs) + + Formset = generic_inlineformset_factory(ForProxyModelModel, fields='__all__', form=SaveTestForm) + instance = ProxyRelatedModel.objects.create() + data = { + 'form-TOTAL_FORMS': '1', + 'form-INITIAL_FORMS': '0', + 'form-MAX_NUM_FORMS': '', + 'form-0-title': 'foo', + } + formset = Formset(data, instance=instance, prefix='form') + self.assertTrue(formset.is_valid()) + new_obj = formset.save()[0] + self.assertEqual(new_obj.saved_by, 'custom method') + + def test_save_new_for_proxy(self): + Formset = generic_inlineformset_factory(ForProxyModelModel, fields='__all__', for_concrete_model=False) + instance = ProxyRelatedModel.objects.create() + data = { + 'form-TOTAL_FORMS': '1', + 'form-INITIAL_FORMS': '0', + 'form-MAX_NUM_FORMS': '', + 'form-0-title': 'foo', + } + formset = Formset(data, instance=instance, prefix='form') + self.assertTrue(formset.is_valid()) + new_obj, = formset.save() + self.assertEqual(new_obj.obj, instance) + + def test_save_new_for_concrete(self): + Formset = generic_inlineformset_factory(ForProxyModelModel, fields='__all__', for_concrete_model=True) + instance = ProxyRelatedModel.objects.create() + data = { + 'form-TOTAL_FORMS': '1', + 'form-INITIAL_FORMS': '0', + 'form-MAX_NUM_FORMS': '', + 'form-0-title': 'foo', + } + formset = Formset(data, instance=instance, prefix='form') + self.assertTrue(formset.is_valid()) + new_obj, = formset.save() + self.assertNotIsInstance(new_obj.obj, ProxyRelatedModel) diff --git a/tests/generic_relations/tests.py b/tests/generic_relations/tests.py index d3aa3b15f8..4c27b6f3d5 100644 --- a/tests/generic_relations/tests.py +++ b/tests/generic_relations/tests.py @@ -1,11 +1,8 @@ -from django import forms -from django.contrib.contenttypes.forms import generic_inlineformset_factory from django.contrib.contenttypes.models import ContentType from django.core.exceptions import FieldError -from django.db import IntegrityError, models +from django.db import IntegrityError from django.db.models import Q from django.test import SimpleTestCase, TestCase -from django.test.utils import isolate_apps from .models import ( AllowsNullGFK, Animal, Carrot, Comparison, ConcreteRelatedModel, @@ -422,73 +419,6 @@ class GenericRelationsTests(TestCase): granite.delete() # deleting the rock should delete the related tag. self.assertEqual(ValuableTaggedItem.objects.count(), 0) - def test_generic_inline_formsets(self): - GenericFormSet = generic_inlineformset_factory(TaggedItem, extra=1) - formset = GenericFormSet() - self.assertHTMLEqual( - ''.join(form.as_p() for form in formset.forms), - """<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag"> -Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" -name="generic_relations-taggeditem-content_type-object_id-0-tag" maxlength="50" /></p> -<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> -<input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" -id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /> -<input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" -id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p>""" - ) - - formset = GenericFormSet(instance=Animal()) - self.assertHTMLEqual( - ''.join(form.as_p() for form in formset.forms), - """<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag"> -Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" -type="text" name="generic_relations-taggeditem-content_type-object_id-0-tag" maxlength="50" /></p> -<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> -<input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" -id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /><input type="hidden" -name="generic_relations-taggeditem-content_type-object_id-0-id" -id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p>""" - ) - - platypus = Animal.objects.create( - common_name="Platypus", latin_name="Ornithorhynchus anatinus" - ) - platypus.tags.create(tag="shiny") - GenericFormSet = generic_inlineformset_factory(TaggedItem, extra=1) - formset = GenericFormSet(instance=platypus) - tagged_item_id = TaggedItem.objects.get( - tag='shiny', object_id=platypus.id - ).id - self.assertHTMLEqual( - ''.join(form.as_p() for form in formset.forms), - """<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-tag">Tag:</label> -<input id="id_generic_relations-taggeditem-content_type-object_id-0-tag" type="text" -name="generic_relations-taggeditem-content_type-object_id-0-tag" value="shiny" maxlength="50" /></p> -<p><label for="id_generic_relations-taggeditem-content_type-object_id-0-DELETE">Delete:</label> -<input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-0-DELETE" -id="id_generic_relations-taggeditem-content_type-object_id-0-DELETE" /> -<input type="hidden" name="generic_relations-taggeditem-content_type-object_id-0-id" -value="%s" id="id_generic_relations-taggeditem-content_type-object_id-0-id" /></p> -<p><label for="id_generic_relations-taggeditem-content_type-object_id-1-tag">Tag:</label> -<input id="id_generic_relations-taggeditem-content_type-object_id-1-tag" type="text" -name="generic_relations-taggeditem-content_type-object_id-1-tag" maxlength="50" /></p> -<p><label for="id_generic_relations-taggeditem-content_type-object_id-1-DELETE">Delete:</label> -<input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-1-DELETE" -id="id_generic_relations-taggeditem-content_type-object_id-1-DELETE" /> -<input type="hidden" name="generic_relations-taggeditem-content_type-object_id-1-id" -id="id_generic_relations-taggeditem-content_type-object_id-1-id" /></p>""" % tagged_item_id - ) - - lion = Animal.objects.create(common_name="Lion", latin_name="Panthera leo") - formset = GenericFormSet(instance=lion, prefix='x') - self.assertHTMLEqual( - ''.join(form.as_p() for form in formset.forms), - """<p><label for="id_x-0-tag">Tag:</label> -<input id="id_x-0-tag" type="text" name="x-0-tag" maxlength="50" /></p> -<p><label for="id_x-0-DELETE">Delete:</label> <input type="checkbox" name="x-0-DELETE" id="id_x-0-DELETE" /> -<input type="hidden" name="x-0-id" id="id_x-0-id" /></p>""" - ) - def test_gfk_manager(self): # GenericForeignKey should not use the default manager (which may filter objects) #16048 tailless = Gecko.objects.create(has_tail=False) @@ -513,22 +443,6 @@ id="id_generic_relations-taggeditem-content_type-object_id-1-id" /></p>""" % tag TaggedItem.objects.create(content_object=bear, tag='orange') self.assertEqual(Carrot.objects.get(tags__tag='orange'), bear) - def test_generic_inline_formsets_initial(self): - """ - Test for #17927 Initial values support for BaseGenericInlineFormSet. - """ - quartz = Mineral.objects.create(name="Quartz", hardness=7) - - GenericFormSet = generic_inlineformset_factory(TaggedItem, extra=1) - ctype = ContentType.objects.get_for_model(quartz) - initial_data = [{ - 'tag': 'lizard', - 'content_type': ctype.pk, - 'object_id': quartz.pk, - }] - formset = GenericFormSet(initial=initial_data) - self.assertEqual(formset.forms[0].initial, initial_data[0]) - def test_get_or_create(self): # get_or_create should work with virtual fields (content_object) quartz = Mineral.objects.create(name="Quartz", hardness=7) @@ -586,98 +500,6 @@ id="id_generic_relations-taggeditem-content_type-object_id-1-id" /></p>""" % tag self.assertEqual(tag.content_object, spinach) -class CustomWidget(forms.TextInput): - pass - - -class TaggedItemForm(forms.ModelForm): - class Meta: - model = TaggedItem - fields = '__all__' - widgets = {'tag': CustomWidget} - - -class GenericInlineFormsetTest(TestCase): - def test_generic_inlineformset_factory(self): - """ - Regression for #14572: Using base forms with widgets - defined in Meta should not raise errors. - """ - Formset = generic_inlineformset_factory(TaggedItem, TaggedItemForm) - form = Formset().forms[0] - self.assertIsInstance(form['tag'].field.widget, CustomWidget) - - @isolate_apps('generic_relations') - def test_incorrect_content_type(self): - class BadModel(models.Model): - content_type = models.PositiveIntegerField() - - msg = "fk_name 'generic_relations.BadModel.content_type' is not a ForeignKey to ContentType" - with self.assertRaisesMessage(Exception, msg): - generic_inlineformset_factory(BadModel, TaggedItemForm) - - def test_save_new_uses_form_save(self): - """ - Regression for #16260: save_new should call form.save() - """ - class SaveTestForm(forms.ModelForm): - def save(self, *args, **kwargs): - self.instance.saved_by = "custom method" - return super().save(*args, **kwargs) - - Formset = generic_inlineformset_factory(ForProxyModelModel, fields='__all__', form=SaveTestForm) - - instance = ProxyRelatedModel.objects.create() - - data = { - 'form-TOTAL_FORMS': '1', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - 'form-0-title': 'foo', - } - - formset = Formset(data, instance=instance, prefix='form') - self.assertTrue(formset.is_valid()) - new_obj = formset.save()[0] - self.assertEqual(new_obj.saved_by, "custom method") - - def test_save_new_for_proxy(self): - Formset = generic_inlineformset_factory(ForProxyModelModel, fields='__all__', for_concrete_model=False) - - instance = ProxyRelatedModel.objects.create() - - data = { - 'form-TOTAL_FORMS': '1', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - 'form-0-title': 'foo', - } - - formset = Formset(data, instance=instance, prefix='form') - self.assertTrue(formset.is_valid()) - - new_obj, = formset.save() - self.assertEqual(new_obj.obj, instance) - - def test_save_new_for_concrete(self): - Formset = generic_inlineformset_factory(ForProxyModelModel, fields='__all__', for_concrete_model=True) - - instance = ProxyRelatedModel.objects.create() - - data = { - 'form-TOTAL_FORMS': '1', - 'form-INITIAL_FORMS': '0', - 'form-MAX_NUM_FORMS': '', - 'form-0-title': 'foo', - } - - formset = Formset(data, instance=instance, prefix='form') - self.assertTrue(formset.is_valid()) - - new_obj, = formset.save() - self.assertNotIsInstance(new_obj.obj, ProxyRelatedModel) - - class ProxyRelatedModelTest(TestCase): def test_default_behavior(self): """ |
