Browse Source

Moved generic_inlineformset_factory() tests to a separate file.

Tim Graham 7 năm trước cách đây
mục cha
commit
46d1af2e82

+ 0 - 105
tests/generic_inline_admin/tests.py

@@ -2,7 +2,6 @@ from django.contrib import admin
 from django.contrib.admin.sites import AdminSite
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.admin import GenericTabularInline
-from django.contrib.contenttypes.forms import generic_inlineformset_factory
 from django.contrib.contenttypes.models import ContentType
 from django.forms.formsets import DEFAULT_MAX_NUM
 from django.forms.models import ModelForm
@@ -89,110 +88,6 @@ class GenericAdminViewTest(TestDataMixin, TestCase):
         response = self.client.post(url, post_data)
         self.assertEqual(response.status_code, 302)  # redirect somewhere
 
-    def test_generic_inline_formset(self):
-        EpisodeMediaFormSet = generic_inlineformset_factory(
-            Media,
-            can_delete=False,
-            exclude=['description', 'keywords'],
-            extra=3,
-        )
-        e = Episode.objects.get(name='This Week in Django')
-
-        # Works with no queryset
-        formset = EpisodeMediaFormSet(instance=e)
-        self.assertEqual(len(formset.forms), 5)
-        self.assertHTMLEqual(
-            formset.forms[0].as_p(),
-            '<p><label for="id_generic_inline_admin-media-content_type-object_id-0-url">'
-            'Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-0-url" '
-            'type="url" name="generic_inline_admin-media-content_type-object_id-0-url" '
-            'value="http://example.com/podcast.mp3" maxlength="200" />'
-            '<input type="hidden" name="generic_inline_admin-media-content_type-object_id-0-id" '
-            'value="%s" id="id_generic_inline_admin-media-content_type-object_id-0-id" /></p>'
-            % self.mp3_media_pk
-        )
-        self.assertHTMLEqual(
-            formset.forms[1].as_p(),
-            '<p><label for="id_generic_inline_admin-media-content_type-object_id-1-url">'
-            'Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-1-url" '
-            'type="url" name="generic_inline_admin-media-content_type-object_id-1-url" '
-            'value="http://example.com/logo.png" maxlength="200" />'
-            '<input type="hidden" name="generic_inline_admin-media-content_type-object_id-1-id" '
-            'value="%s" id="id_generic_inline_admin-media-content_type-object_id-1-id" /></p>'
-            % self.png_media_pk
-        )
-        self.assertHTMLEqual(
-            formset.forms[2].as_p(),
-            '<p><label for="id_generic_inline_admin-media-content_type-object_id-2-url">Url:</label>'
-            '<input id="id_generic_inline_admin-media-content_type-object_id-2-url" type="url" '
-            'name="generic_inline_admin-media-content_type-object_id-2-url" maxlength="200" />'
-            '<input type="hidden" name="generic_inline_admin-media-content_type-object_id-2-id" '
-            'id="id_generic_inline_admin-media-content_type-object_id-2-id" /></p>'
-        )
-
-        # A queryset can be used to alter display ordering
-        formset = EpisodeMediaFormSet(instance=e, queryset=Media.objects.order_by('url'))
-        self.assertEqual(len(formset.forms), 5)
-        self.assertHTMLEqual(
-            formset.forms[0].as_p(),
-            '<p><label for="id_generic_inline_admin-media-content_type-object_id-0-url">Url:</label>'
-            '<input id="id_generic_inline_admin-media-content_type-object_id-0-url" type="url" '
-            'name="generic_inline_admin-media-content_type-object_id-0-url"'
-            'value="http://example.com/logo.png" maxlength="200" />'
-            '<input type="hidden" name="generic_inline_admin-media-content_type-object_id-0-id" '
-            'value="%s" id="id_generic_inline_admin-media-content_type-object_id-0-id" /></p>'
-            % self.png_media_pk
-        )
-        self.assertHTMLEqual(
-            formset.forms[1].as_p(),
-            '<p><label for="id_generic_inline_admin-media-content_type-object_id-1-url">Url:</label>'
-            '<input id="id_generic_inline_admin-media-content_type-object_id-1-url" type="url" '
-            'name="generic_inline_admin-media-content_type-object_id-1-url" '
-            'value="http://example.com/podcast.mp3" maxlength="200" />'
-            '<input type="hidden" name="generic_inline_admin-media-content_type-object_id-1-id" '
-            'value="%s" id="id_generic_inline_admin-media-content_type-object_id-1-id" /></p>'
-            % self.mp3_media_pk
-        )
-        self.assertHTMLEqual(
-            formset.forms[2].as_p(),
-            '<p><label for="id_generic_inline_admin-media-content_type-object_id-2-url">'
-            'Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-2-url" '
-            'type="url" name="generic_inline_admin-media-content_type-object_id-2-url" maxlength="200" />'
-            '<input type="hidden" name="generic_inline_admin-media-content_type-object_id-2-id" '
-            'id="id_generic_inline_admin-media-content_type-object_id-2-id" /></p>'
-        )
-
-        # Works with a queryset that omits items
-        formset = EpisodeMediaFormSet(instance=e, queryset=Media.objects.filter(url__endswith=".png"))
-        self.assertEqual(len(formset.forms), 4)
-        self.assertHTMLEqual(
-            formset.forms[0].as_p(),
-            '<p><label for="id_generic_inline_admin-media-content_type-object_id-0-url">Url:</label>'
-            ' <input id="id_generic_inline_admin-media-content_type-object_id-0-url" type="url" '
-            'name="generic_inline_admin-media-content_type-object_id-0-url" '
-            'value="http://example.com/logo.png" maxlength="200" />'
-            '<input type="hidden" name="generic_inline_admin-media-content_type-object_id-0-id" '
-            'value="%s" id="id_generic_inline_admin-media-content_type-object_id-0-id" /></p>'
-            % self.png_media_pk
-        )
-        self.assertHTMLEqual(
-            formset.forms[1].as_p(),
-            '<p><label for="id_generic_inline_admin-media-content_type-object_id-1-url">'
-            'Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-1-url" '
-            'type="url" name="generic_inline_admin-media-content_type-object_id-1-url" maxlength="200" />'
-            '<input type="hidden" name="generic_inline_admin-media-content_type-object_id-1-id" '
-            'id="id_generic_inline_admin-media-content_type-object_id-1-id" /></p>'
-        )
-
-    def test_generic_inline_formset_factory(self):
-        # Regression test for #10522.
-        inline_formset = generic_inlineformset_factory(Media, exclude=('url',))
-
-        # Regression test for #12340.
-        e = Episode.objects.get(name='This Week in Django')
-        formset = inline_formset(instance=e)
-        self.assertTrue(formset.get_queryset().ordered)
-
 
 @override_settings(ROOT_URLCONF='generic_inline_admin.urls')
 class GenericInlineAdminParametersTest(TestDataMixin, TestCase):

+ 202 - 0
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)

+ 1 - 179
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):
         """