diff options
| author | Brian Rosner <brosner@gmail.com> | 2008-10-31 22:07:05 +0000 |
|---|---|---|
| committer | Brian Rosner <brosner@gmail.com> | 2008-10-31 22:07:05 +0000 |
| commit | 0ea15f5650bc83483fc4ac18b379ae4add373573 (patch) | |
| tree | c27c0a4f1241dbfc3d38f0eb1be3d5316d86be7a /tests | |
| parent | fe54f06a61ff55bcf7e233e7e11d633bae0cf36f (diff) | |
Fixed #8882 -- When a foreign key is among the unique_together fields in an inline formset properly handle it.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@9297 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/modeltests/model_formsets/models.py | 84 |
1 files changed, 67 insertions, 17 deletions
diff --git a/tests/modeltests/model_formsets/models.py b/tests/modeltests/model_formsets/models.py index 215f35b59a..4bf7b40eae 100644 --- a/tests/modeltests/model_formsets/models.py +++ b/tests/modeltests/model_formsets/models.py @@ -96,6 +96,24 @@ class Price(models.Model): class MexicanRestaurant(Restaurant): serves_tacos = models.BooleanField() +# models for testing unique_together validation when a fk is involved and +# using inlineformset_factory. +class Repository(models.Model): + name = models.CharField(max_length=25) + + def __unicode__(self): + return self.name + +class Revision(models.Model): + repository = models.ForeignKey(Repository) + revision = models.CharField(max_length=40) + + class Meta: + unique_together = (("repository", "revision"),) + + def __unicode__(self): + return u"%s (%s)" % (self.revision, unicode(self.repository)) + # models for testing callable defaults (see bug #7975). If you define a model # with a callable default value, you cannot rely on the initial value in a # form. @@ -375,9 +393,9 @@ admin system's edit inline functionality works. >>> formset = AuthorBooksFormSet(instance=author) >>> for form in formset.forms: ... print form.as_p() -<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" maxlength="100" /><input type="hidden" name="book_set-0-id" id="id_book_set-0-id" /></p> -<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" maxlength="100" /><input type="hidden" name="book_set-1-id" id="id_book_set-1-id" /></p> -<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" maxlength="100" /><input type="hidden" name="book_set-2-id" id="id_book_set-2-id" /></p> +<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" maxlength="100" /><input type="hidden" name="book_set-0-author" value="1" id="id_book_set-0-author" /><input type="hidden" name="book_set-0-id" id="id_book_set-0-id" /></p> +<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" maxlength="100" /><input type="hidden" name="book_set-1-author" value="1" id="id_book_set-1-author" /><input type="hidden" name="book_set-1-id" id="id_book_set-1-id" /></p> +<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" maxlength="100" /><input type="hidden" name="book_set-2-author" value="1" id="id_book_set-2-author" /><input type="hidden" name="book_set-2-id" id="id_book_set-2-id" /></p> >>> data = { ... 'book_set-TOTAL_FORMS': '3', # the number of forms rendered @@ -409,9 +427,9 @@ book. >>> formset = AuthorBooksFormSet(instance=author) >>> for form in formset.forms: ... print form.as_p() -<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" value="Les Fleurs du Mal" maxlength="100" /><input type="hidden" name="book_set-0-id" value="1" id="id_book_set-0-id" /></p> -<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" maxlength="100" /><input type="hidden" name="book_set-1-id" id="id_book_set-1-id" /></p> -<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" maxlength="100" /><input type="hidden" name="book_set-2-id" id="id_book_set-2-id" /></p> +<p><label for="id_book_set-0-title">Title:</label> <input id="id_book_set-0-title" type="text" name="book_set-0-title" value="Les Fleurs du Mal" maxlength="100" /><input type="hidden" name="book_set-0-author" value="1" id="id_book_set-0-author" /><input type="hidden" name="book_set-0-id" value="1" id="id_book_set-0-id" /></p> +<p><label for="id_book_set-1-title">Title:</label> <input id="id_book_set-1-title" type="text" name="book_set-1-title" maxlength="100" /><input type="hidden" name="book_set-1-author" value="1" id="id_book_set-1-author" /><input type="hidden" name="book_set-1-id" id="id_book_set-1-id" /></p> +<p><label for="id_book_set-2-title">Title:</label> <input id="id_book_set-2-title" type="text" name="book_set-2-title" maxlength="100" /><input type="hidden" name="book_set-2-author" value="1" id="id_book_set-2-author" /><input type="hidden" name="book_set-2-id" id="id_book_set-2-id" /></p> >>> data = { ... 'book_set-TOTAL_FORMS': '3', # the number of forms rendered @@ -454,7 +472,7 @@ This is used in the admin for save_as functionality. True >>> new_author = Author.objects.create(name='Charles Baudelaire') ->>> formset.instance = new_author +>>> formset = AuthorBooksFormSet(data, instance=new_author, save_as_new=True) >>> [book for book in formset.save() if book.author.pk == new_author.pk] [<Book: Les Fleurs du Mal>, <Book: Le Spleen de Paris>] @@ -463,8 +481,8 @@ Test using a custom prefix on an inline formset. >>> formset = AuthorBooksFormSet(prefix="test") >>> for form in formset.forms: ... print form.as_p() -<p><label for="id_test-0-title">Title:</label> <input id="id_test-0-title" type="text" name="test-0-title" maxlength="100" /><input type="hidden" name="test-0-id" id="id_test-0-id" /></p> -<p><label for="id_test-1-title">Title:</label> <input id="id_test-1-title" type="text" name="test-1-title" maxlength="100" /><input type="hidden" name="test-1-id" id="id_test-1-id" /></p> +<p><label for="id_test-0-title">Title:</label> <input id="id_test-0-title" type="text" name="test-0-title" maxlength="100" /><input type="hidden" name="test-0-author" id="id_test-0-author" /><input type="hidden" name="test-0-id" id="id_test-0-id" /></p> +<p><label for="id_test-1-title">Title:</label> <input id="id_test-1-title" type="text" name="test-1-title" maxlength="100" /><input type="hidden" name="test-1-author" id="id_test-1-author" /><input type="hidden" name="test-1-id" id="id_test-1-id" /></p> # Test a custom primary key ################################################### @@ -486,8 +504,8 @@ We need to ensure that it is displayed >>> formset = FormSet(instance=place) >>> for form in formset.forms: ... print form.as_p() -<p><label for="id_owner_set-0-name">Name:</label> <input id="id_owner_set-0-name" type="text" name="owner_set-0-name" maxlength="100" /><input type="hidden" name="owner_set-0-auto_id" id="id_owner_set-0-auto_id" /></p> -<p><label for="id_owner_set-1-name">Name:</label> <input id="id_owner_set-1-name" type="text" name="owner_set-1-name" maxlength="100" /><input type="hidden" name="owner_set-1-auto_id" id="id_owner_set-1-auto_id" /></p> +<p><label for="id_owner_set-0-name">Name:</label> <input id="id_owner_set-0-name" type="text" name="owner_set-0-name" maxlength="100" /><input type="hidden" name="owner_set-0-place" value="1" id="id_owner_set-0-place" /><input type="hidden" name="owner_set-0-auto_id" id="id_owner_set-0-auto_id" /></p> +<p><label for="id_owner_set-1-name">Name:</label> <input id="id_owner_set-1-name" type="text" name="owner_set-1-name" maxlength="100" /><input type="hidden" name="owner_set-1-place" value="1" id="id_owner_set-1-place" /><input type="hidden" name="owner_set-1-auto_id" id="id_owner_set-1-auto_id" /></p> >>> data = { ... 'owner_set-TOTAL_FORMS': '2', @@ -506,9 +524,9 @@ True >>> formset = FormSet(instance=place) >>> for form in formset.forms: ... print form.as_p() -<p><label for="id_owner_set-0-name">Name:</label> <input id="id_owner_set-0-name" type="text" name="owner_set-0-name" value="Joe Perry" maxlength="100" /><input type="hidden" name="owner_set-0-auto_id" value="1" id="id_owner_set-0-auto_id" /></p> -<p><label for="id_owner_set-1-name">Name:</label> <input id="id_owner_set-1-name" type="text" name="owner_set-1-name" maxlength="100" /><input type="hidden" name="owner_set-1-auto_id" id="id_owner_set-1-auto_id" /></p> -<p><label for="id_owner_set-2-name">Name:</label> <input id="id_owner_set-2-name" type="text" name="owner_set-2-name" maxlength="100" /><input type="hidden" name="owner_set-2-auto_id" id="id_owner_set-2-auto_id" /></p> +<p><label for="id_owner_set-0-name">Name:</label> <input id="id_owner_set-0-name" type="text" name="owner_set-0-name" value="Joe Perry" maxlength="100" /><input type="hidden" name="owner_set-0-place" value="1" id="id_owner_set-0-place" /><input type="hidden" name="owner_set-0-auto_id" value="1" id="id_owner_set-0-auto_id" /></p> +<p><label for="id_owner_set-1-name">Name:</label> <input id="id_owner_set-1-name" type="text" name="owner_set-1-name" maxlength="100" /><input type="hidden" name="owner_set-1-place" value="1" id="id_owner_set-1-place" /><input type="hidden" name="owner_set-1-auto_id" id="id_owner_set-1-auto_id" /></p> +<p><label for="id_owner_set-2-name">Name:</label> <input id="id_owner_set-2-name" type="text" name="owner_set-2-name" maxlength="100" /><input type="hidden" name="owner_set-2-place" value="1" id="id_owner_set-2-place" /><input type="hidden" name="owner_set-2-auto_id" id="id_owner_set-2-auto_id" /></p> >>> data = { ... 'owner_set-TOTAL_FORMS': '3', @@ -545,7 +563,7 @@ True >>> formset = FormSet(instance=owner) >>> for form in formset.forms: ... print form.as_p() -<p><label for="id_ownerprofile-0-age">Age:</label> <input type="text" name="ownerprofile-0-age" id="id_ownerprofile-0-age" /><input type="hidden" name="ownerprofile-0-owner" id="id_ownerprofile-0-owner" /></p> +<p><label for="id_ownerprofile-0-age">Age:</label> <input type="text" name="ownerprofile-0-age" id="id_ownerprofile-0-age" /><input type="hidden" name="ownerprofile-0-owner" value="1" id="id_ownerprofile-0-owner" /></p> >>> data = { ... 'ownerprofile-TOTAL_FORMS': '1', @@ -583,7 +601,7 @@ True >>> for form in formset.forms: ... print form.as_p() <p><label for="id_location_set-0-lat">Lat:</label> <input id="id_location_set-0-lat" type="text" name="location_set-0-lat" maxlength="100" /></p> -<p><label for="id_location_set-0-lon">Lon:</label> <input id="id_location_set-0-lon" type="text" name="location_set-0-lon" maxlength="100" /><input type="hidden" name="location_set-0-id" id="id_location_set-0-id" /></p> +<p><label for="id_location_set-0-lon">Lon:</label> <input id="id_location_set-0-lon" type="text" name="location_set-0-lon" maxlength="100" /><input type="hidden" name="location_set-0-place" value="1" id="id_location_set-0-place" /><input type="hidden" name="location_set-0-id" id="id_location_set-0-id" /></p> # Foreign keys in parents ######################################## @@ -646,6 +664,38 @@ False >>> formset.errors [{'__all__': [u'Price with this Price and Quantity already exists.']}] +# unique_together with inlineformset_factory +# Also see bug #8882. + +>>> repository = Repository.objects.create(name=u'Test Repo') +>>> FormSet = inlineformset_factory(Repository, Revision, extra=1) +>>> data = { +... 'revision_set-TOTAL_FORMS': '1', +... 'revision_set-INITIAL_FORMS': '0', +... 'revision_set-0-repository': repository.pk, +... 'revision_set-0-revision': '146239817507f148d448db38840db7c3cbf47c76', +... 'revision_set-0-DELETE': '', +... } +>>> formset = FormSet(data, instance=repository) +>>> formset.is_valid() +True +>>> formset.save() +[<Revision: 146239817507f148d448db38840db7c3cbf47c76 (Test Repo)>] + +# attempt to save the same revision against against the same repo. +>>> data = { +... 'revision_set-TOTAL_FORMS': '1', +... 'revision_set-INITIAL_FORMS': '0', +... 'revision_set-0-repository': repository.pk, +... 'revision_set-0-revision': '146239817507f148d448db38840db7c3cbf47c76', +... 'revision_set-0-DELETE': '', +... } +>>> formset = FormSet(data, instance=repository) +>>> formset.is_valid() +False +>>> formset.errors +[{'__all__': [u'Revision with this Repository and Revision already exists.']}] + # Use of callable defaults (see bug #7975). >>> person = Person.objects.create(name='Ringo') @@ -660,7 +710,7 @@ False >>> now = form.fields['date_joined'].initial >>> print form.as_p() <p><label for="id_membership_set-0-date_joined">Date joined:</label> <input type="text" name="membership_set-0-date_joined" value="..." id="id_membership_set-0-date_joined" /><input type="hidden" name="initial-membership_set-0-date_joined" value="..." id="id_membership_set-0-date_joined" /></p> -<p><label for="id_membership_set-0-karma">Karma:</label> <input type="text" name="membership_set-0-karma" id="id_membership_set-0-karma" /><input type="hidden" name="membership_set-0-id" id="id_membership_set-0-id" /></p> +<p><label for="id_membership_set-0-karma">Karma:</label> <input type="text" name="membership_set-0-karma" id="id_membership_set-0-karma" /><input type="hidden" name="membership_set-0-person" value="1" id="id_membership_set-0-person" /><input type="hidden" name="membership_set-0-id" id="id_membership_set-0-id" /></p> # test for validation with callable defaults. Validations rely on hidden fields |
