mirror of
https://github.com/django/django.git
synced 2025-08-03 18:38:50 +00:00
Fixed #9493 -- Corrected error handling of formsets that violate unique constraints across the component forms. Thanks to Alex Gaynor for the patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10682 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
eb81d5acb3
commit
f259494f82
3 changed files with 316 additions and 51 deletions
|
@ -23,6 +23,12 @@ class Book(models.Model):
|
|||
author = models.ForeignKey(Author)
|
||||
title = models.CharField(max_length=100)
|
||||
|
||||
class Meta:
|
||||
unique_together = (
|
||||
('author', 'title'),
|
||||
)
|
||||
ordering = ['id']
|
||||
|
||||
def __unicode__(self):
|
||||
return self.title
|
||||
|
||||
|
@ -58,7 +64,7 @@ class CustomPrimaryKey(models.Model):
|
|||
class Place(models.Model):
|
||||
name = models.CharField(max_length=50)
|
||||
city = models.CharField(max_length=50)
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
@ -85,7 +91,7 @@ class OwnerProfile(models.Model):
|
|||
|
||||
class Restaurant(Place):
|
||||
serves_pizza = models.BooleanField()
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
@ -166,6 +172,15 @@ class Poem(models.Model):
|
|||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Post(models.Model):
|
||||
title = models.CharField(max_length=50, unique_for_date='posted', blank=True)
|
||||
slug = models.CharField(max_length=50, unique_for_year='posted', blank=True)
|
||||
subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True)
|
||||
posted = models.DateField()
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
__test__ = {'API_TESTS': """
|
||||
|
||||
>>> from datetime import date
|
||||
|
@ -573,7 +588,7 @@ True
|
|||
... print book.title
|
||||
Les Fleurs du Mal
|
||||
|
||||
Test inline formsets where the inline-edited object uses multi-table inheritance, thus
|
||||
Test inline formsets where the inline-edited object uses multi-table inheritance, thus
|
||||
has a non AutoField yet auto-created primary key.
|
||||
|
||||
>>> AuthorBooksFormSet3 = inlineformset_factory(Author, AlternateBook, can_delete=False, extra=1)
|
||||
|
@ -740,7 +755,7 @@ True
|
|||
>>> formset.save()
|
||||
[<OwnerProfile: Joe Perry is 55>]
|
||||
|
||||
# ForeignKey with unique=True should enforce max_num=1
|
||||
# ForeignKey with unique=True should enforce max_num=1
|
||||
|
||||
>>> FormSet = inlineformset_factory(Place, Location, can_delete=False)
|
||||
>>> formset = FormSet(instance=place)
|
||||
|
@ -943,4 +958,129 @@ True
|
|||
>>> FormSet = modelformset_factory(ClassyMexicanRestaurant, fields=["tacos_are_yummy"])
|
||||
>>> sorted(FormSet().forms[0].fields.keys())
|
||||
['restaurant', 'tacos_are_yummy']
|
||||
|
||||
# Prevent duplicates from within the same formset
|
||||
>>> FormSet = modelformset_factory(Product, extra=2)
|
||||
>>> data = {
|
||||
... 'form-TOTAL_FORMS': 2,
|
||||
... 'form-INITIAL_FORMS': 0,
|
||||
... 'form-0-slug': 'red_car',
|
||||
... 'form-1-slug': 'red_car',
|
||||
... }
|
||||
>>> formset = FormSet(data)
|
||||
>>> formset.is_valid()
|
||||
False
|
||||
>>> formset._non_form_errors
|
||||
[u'Please correct the duplicate data for slug.']
|
||||
|
||||
>>> FormSet = modelformset_factory(Price, extra=2)
|
||||
>>> data = {
|
||||
... 'form-TOTAL_FORMS': 2,
|
||||
... 'form-INITIAL_FORMS': 0,
|
||||
... 'form-0-price': '25',
|
||||
... 'form-0-quantity': '7',
|
||||
... 'form-1-price': '25',
|
||||
... 'form-1-quantity': '7',
|
||||
... }
|
||||
>>> formset = FormSet(data)
|
||||
>>> formset.is_valid()
|
||||
False
|
||||
>>> formset._non_form_errors
|
||||
[u'Please correct the duplicate data for price and quantity, which must be unique.']
|
||||
|
||||
# only the price field is specified, this should skip any unique checks since the unique_together is not fulfilled.
|
||||
# this will fail with a KeyError if broken.
|
||||
>>> FormSet = modelformset_factory(Price, fields=("price",), extra=2)
|
||||
>>> data = {
|
||||
... 'form-TOTAL_FORMS': '2',
|
||||
... 'form-INITIAL_FORMS': '0',
|
||||
... 'form-0-price': '24',
|
||||
... 'form-1-price': '24',
|
||||
... }
|
||||
>>> formset = FormSet(data)
|
||||
>>> formset.is_valid()
|
||||
True
|
||||
|
||||
>>> FormSet = inlineformset_factory(Author, Book, extra=0)
|
||||
>>> author = Author.objects.order_by('id')[0]
|
||||
>>> book_ids = author.book_set.values_list('id', flat=True)
|
||||
>>> data = {
|
||||
... 'book_set-TOTAL_FORMS': '2',
|
||||
... 'book_set-INITIAL_FORMS': '2',
|
||||
...
|
||||
... 'book_set-0-title': 'The 2008 Election',
|
||||
... 'book_set-0-author': str(author.id),
|
||||
... 'book_set-0-id': str(book_ids[0]),
|
||||
...
|
||||
... 'book_set-1-title': 'The 2008 Election',
|
||||
... 'book_set-1-author': str(author.id),
|
||||
... 'book_set-1-id': str(book_ids[1]),
|
||||
... }
|
||||
>>> formset = FormSet(data=data, instance=author)
|
||||
>>> formset.is_valid()
|
||||
False
|
||||
>>> formset._non_form_errors
|
||||
[u'Please correct the duplicate data for title.']
|
||||
>>> formset.errors
|
||||
[{}, {'__all__': u'Please correct the duplicate values below.'}]
|
||||
|
||||
>>> FormSet = modelformset_factory(Post, extra=2)
|
||||
>>> data = {
|
||||
... 'form-TOTAL_FORMS': '2',
|
||||
... 'form-INITIAL_FORMS': '0',
|
||||
...
|
||||
... 'form-0-title': 'blah',
|
||||
... 'form-0-slug': 'Morning',
|
||||
... 'form-0-subtitle': 'foo',
|
||||
... 'form-0-posted': '2009-01-01',
|
||||
... 'form-1-title': 'blah',
|
||||
... 'form-1-slug': 'Morning in Prague',
|
||||
... 'form-1-subtitle': 'rawr',
|
||||
... 'form-1-posted': '2009-01-01'
|
||||
... }
|
||||
>>> formset = FormSet(data)
|
||||
>>> formset.is_valid()
|
||||
False
|
||||
>>> formset._non_form_errors
|
||||
[u'Please correct the duplicate data for title which must be unique for the date in posted.']
|
||||
>>> formset.errors
|
||||
[{}, {'__all__': u'Please correct the duplicate values below.'}]
|
||||
|
||||
>>> data = {
|
||||
... 'form-TOTAL_FORMS': '2',
|
||||
... 'form-INITIAL_FORMS': '0',
|
||||
...
|
||||
... 'form-0-title': 'foo',
|
||||
... 'form-0-slug': 'Morning in Prague',
|
||||
... 'form-0-subtitle': 'foo',
|
||||
... 'form-0-posted': '2009-01-01',
|
||||
... 'form-1-title': 'blah',
|
||||
... 'form-1-slug': 'Morning in Prague',
|
||||
... 'form-1-subtitle': 'rawr',
|
||||
... 'form-1-posted': '2009-08-02'
|
||||
... }
|
||||
>>> formset = FormSet(data)
|
||||
>>> formset.is_valid()
|
||||
False
|
||||
>>> formset._non_form_errors
|
||||
[u'Please correct the duplicate data for slug which must be unique for the year in posted.']
|
||||
|
||||
>>> data = {
|
||||
... 'form-TOTAL_FORMS': '2',
|
||||
... 'form-INITIAL_FORMS': '0',
|
||||
...
|
||||
... 'form-0-title': 'foo',
|
||||
... 'form-0-slug': 'Morning in Prague',
|
||||
... 'form-0-subtitle': 'rawr',
|
||||
... 'form-0-posted': '2008-08-01',
|
||||
... 'form-1-title': 'blah',
|
||||
... 'form-1-slug': 'Prague',
|
||||
... 'form-1-subtitle': 'rawr',
|
||||
... 'form-1-posted': '2009-08-02'
|
||||
... }
|
||||
>>> formset = FormSet(data)
|
||||
>>> formset.is_valid()
|
||||
False
|
||||
>>> formset._non_form_errors
|
||||
[u'Please correct the duplicate data for subtitle which must be unique for the month in posted.']
|
||||
"""}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue