Fixed #13126 -- Ensured that individual form errors are displayed when errors occur on a list-editable changelist. Thanks to slafs for the report, and to Julien Phalip for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15580 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2011-02-19 11:48:42 +00:00
parent de161fbf21
commit 791ecb4be4
4 changed files with 95 additions and 5 deletions

View File

@ -16,7 +16,10 @@
</thead>
<tbody>
{% for result in results %}
<tr class="{% cycle 'row1' 'row2' %}">{% for item in result %}{{ item }}{% endfor %}</tr>
{% if result.form.non_field_errors %}
<tr><td colspan="{{ result.row|length }}">{{ result.form.non_field_errors }}</td></tr>
{% endif %}
<tr class="{% cycle 'row1' 'row2' %}">{% for item in result.row %}{{ item }}{% endfor %}</tr>
{% endfor %}
</tbody>
</table>

View File

@ -198,10 +198,10 @@ def items_for_result(cl, result, form):
def results(cl):
if cl.formset:
for res, form in zip(cl.result_list, cl.formset.forms):
yield list(items_for_result(cl, res, form))
yield {'row': list(items_for_result(cl, res, form)), 'form': form}
else:
for res in cl.result_list:
yield list(items_for_result(cl, res, None))
yield {'row': list(items_for_result(cl, res, None)), 'form': None}
def result_hidden_fields(cl):
if cl.formset:

View File

@ -669,7 +669,32 @@ class Answer(models.Model):
class Reservation(models.Model):
start_date = models.DateTimeField()
price = models.IntegerField()
DRIVER_CHOICES = (
(u'bill', 'Bill G'),
(u'steve', 'Steve J'),
)
RESTAURANT_CHOICES = (
(u'indian', u'A Taste of India'),
(u'thai', u'Thai Pography'),
(u'pizza', u'Pizza Mama'),
)
class FoodDelivery(models.Model):
reference = models.CharField(max_length=100)
driver = models.CharField(max_length=100, choices=DRIVER_CHOICES, blank=True)
restaurant = models.CharField(max_length=100, choices=RESTAURANT_CHOICES, blank=True)
class Meta:
unique_together = (("driver", "restaurant"),)
class FoodDeliveryAdmin(admin.ModelAdmin):
list_display=('reference', 'driver', 'restaurant')
list_editable = ('driver', 'restaurant')
admin.site.register(Article, ArticleAdmin)
admin.site.register(CustomArticle, CustomArticleAdmin)
admin.site.register(Section, save_as=True, inlines=[ArticleInline])
@ -706,6 +731,7 @@ admin.site.register(CyclicOne)
admin.site.register(CyclicTwo)
admin.site.register(WorkHour, WorkHourAdmin)
admin.site.register(Reservation)
admin.site.register(FoodDelivery, FoodDeliveryAdmin)
# We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
# That way we cover all four cases:

View File

@ -35,7 +35,7 @@ from models import (Article, BarAccount, CustomArticle, EmptyModel,
Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast,
Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit,
Category, Post, Plot, FunkyTag, Chapter, Book, Promo, WorkHour, Employee,
Question, Answer, Inquisition, Actor)
Question, Answer, Inquisition, Actor, FoodDelivery)
class AdminViewBasicTest(TestCase):
@ -1420,6 +1420,67 @@ class AdminViewListEditable(TestCase):
self.assertEqual(Person.objects.get(name="John Mauchly").alive, False)
def test_non_field_errors(self):
''' Ensure that non field errors are displayed for each of the
forms in the changelist's formset. Refs #13126.
'''
FoodDelivery.objects.create(reference='123', driver='bill', restaurant='thai')
FoodDelivery.objects.create(reference='456', driver='bill', restaurant='india')
FoodDelivery.objects.create(reference='789', driver='bill', restaurant='pizza')
data = {
"form-TOTAL_FORMS": "3",
"form-INITIAL_FORMS": "3",
"form-MAX_NUM_FORMS": "0",
"form-0-id": "1",
"form-0-reference": "123",
"form-0-driver": "bill",
"form-0-restaurant": "thai",
# Same data as above: Forbidden because of unique_together!
"form-1-id": "2",
"form-1-reference": "456",
"form-1-driver": "bill",
"form-1-restaurant": "thai",
"form-2-id": "3",
"form-2-reference": "789",
"form-2-driver": "bill",
"form-2-restaurant": "pizza",
"_save": "Save",
}
response = self.client.post('/test_admin/admin/admin_views/fooddelivery/', data)
self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist"><li>Food delivery with this Driver and Restaurant already exists.</li></ul></td></tr>', 1)
data = {
"form-TOTAL_FORMS": "3",
"form-INITIAL_FORMS": "3",
"form-MAX_NUM_FORMS": "0",
"form-0-id": "1",
"form-0-reference": "123",
"form-0-driver": "bill",
"form-0-restaurant": "thai",
# Same data as above: Forbidden because of unique_together!
"form-1-id": "2",
"form-1-reference": "456",
"form-1-driver": "bill",
"form-1-restaurant": "thai",
# Same data also.
"form-2-id": "3",
"form-2-reference": "789",
"form-2-driver": "bill",
"form-2-restaurant": "thai",
"_save": "Save",
}
response = self.client.post('/test_admin/admin/admin_views/fooddelivery/', data)
self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist"><li>Food delivery with this Driver and Restaurant already exists.</li></ul></td></tr>', 2)
def test_non_form_errors(self):
# test if non-form errors are handled; ticket #12716
data = {