Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.2.X] Fixed #13510 -- Corrected colspan of non-field-specific error…

… messages in admin app tabular inlines so it isn't greater than the actual number of field cells. Thanks KyleMac for the report and Julien Phalip for the patch fixing the issue.

Backport of [15626] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15627 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit dc9d639c0aeb0e3c239d9a20f7aa51e7a3d5261b 1 parent 53663be
Ramiro Morales authored February 22, 2011
4  django/contrib/admin/templates/admin/edit_inline/tabular.html
... ...
@@ -1,4 +1,4 @@
1  
-{% load i18n adminmedia %}
  1
+{% load i18n adminmedia admin_modify %}
2 2
 <div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group">
3 3
   <div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
4 4
 {{ inline_admin_formset.formset.management_form }}
@@ -18,7 +18,7 @@
18 18
      <tbody>
19 19
      {% for inline_admin_form in inline_admin_formset %}
20 20
         {% if inline_admin_form.form.non_field_errors %}
21  
-        <tr><td colspan="{{ inline_admin_form.field_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr>
  21
+        <tr><td colspan="{{ inline_admin_form|cell_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr>
22 22
         {% endif %}
23 23
         <tr class="{% cycle "row1" "row2" %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last %} empty-form{% endif %}"
24 24
              id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
18  django/contrib/admin/templatetags/admin_modify.py
@@ -21,7 +21,7 @@ def prepopulated_fields_js(context):
21 21
 
22 22
 def submit_row(context):
23 23
     """
24  
-    Displays the row of buttons for delete and save. 
  24
+    Displays the row of buttons for delete and save.
25 25
     """
26 26
     opts = context['opts']
27 27
     change = context['change']
@@ -33,10 +33,24 @@ def submit_row(context):
33 33
         'show_delete_link': (not is_popup and context['has_delete_permission']
34 34
                               and (change or context['show_delete'])),
35 35
         'show_save_as_new': not is_popup and change and save_as,
36  
-        'show_save_and_add_another': context['has_add_permission'] and 
  36
+        'show_save_and_add_another': context['has_add_permission'] and
37 37
                             not is_popup and (not save_as or context['add']),
38 38
         'show_save_and_continue': not is_popup and context['has_change_permission'],
39 39
         'is_popup': is_popup,
40 40
         'show_save': True
41 41
     }
42 42
 submit_row = register.inclusion_tag('admin/submit_line.html', takes_context=True)(submit_row)
  43
+
  44
+def cell_count(inline_admin_form):
  45
+    """Returns the number of cells used in a tabular inline"""
  46
+    count = 1 # Hidden cell with hidden 'id' field
  47
+    for fieldset in inline_admin_form:
  48
+        # Loop through all the fields (one per cell)
  49
+        for line in fieldset:
  50
+            for field in line:
  51
+                count += 1
  52
+    if inline_admin_form.formset.can_delete:
  53
+        # Delete checkbox
  54
+        count += 1
  55
+    return count
  56
+cell_count = register.filter(cell_count)
28  tests/regressiontests/admin_inlines/models.py
@@ -6,6 +6,7 @@
6 6
 from django.contrib import admin
7 7
 from django.contrib.contenttypes.models import ContentType
8 8
 from django.contrib.contenttypes import generic
  9
+from django import forms
9 10
 
10 11
 class Parent(models.Model):
11 12
     name = models.CharField(max_length=50)
@@ -123,3 +124,30 @@ class InlineWeakness(admin.TabularInline):
123 124
     extra = 1
124 125
 
125 126
 admin.site.register(Fashionista, inlines=[InlineWeakness])
  127
+
  128
+# Models for #13510
  129
+
  130
+class TitleCollection(models.Model):
  131
+    pass
  132
+
  133
+class Title(models.Model):
  134
+    collection = models.ForeignKey(TitleCollection, blank=True, null=True)
  135
+    title1 = models.CharField(max_length=100)
  136
+    title2 = models.CharField(max_length=100)
  137
+
  138
+class TitleForm(forms.ModelForm):
  139
+
  140
+    def clean(self):
  141
+        cleaned_data = self.cleaned_data
  142
+        title1 = cleaned_data.get("title1")
  143
+        title2 = cleaned_data.get("title2")
  144
+        if title1 != title2:
  145
+            raise forms.ValidationError("The two titles must be the same")
  146
+        return cleaned_data
  147
+
  148
+class TitleInline(admin.TabularInline):
  149
+    model = Title
  150
+    form = TitleForm
  151
+    extra = 1
  152
+
  153
+admin.site.register(TitleCollection, inlines=[TitleInline])
17  tests/regressiontests/admin_inlines/tests.py
@@ -67,6 +67,23 @@ def test_inline_primary(self):
67 67
         self.assertEqual(response.status_code, 302)
68 68
         self.assertEqual(len(Fashionista.objects.filter(person__firstname='Imelda')), 1)
69 69
 
  70
+    def test_tabular_non_field_errors(self):
  71
+        """
  72
+        Ensure that non_field_errors are displayed correctly, including the
  73
+        right value for colspan. Refs #13510.
  74
+        """
  75
+        data = {
  76
+            'title_set-TOTAL_FORMS': 1,
  77
+            'title_set-INITIAL_FORMS': 0,
  78
+            'title_set-MAX_NUM_FORMS': 0,
  79
+            '_save': u'Save',
  80
+            'title_set-0-title1': 'a title',
  81
+            'title_set-0-title2': 'a different title',
  82
+        }
  83
+        response = self.client.post('/test_admin/admin/admin_inlines/titlecollection/add/', data)
  84
+        # Here colspan is "4": two fields (title1 and title2), one hidden field and the delete checkbock.
  85
+        self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist"><li>The two titles must be the same</li></ul></td></tr>')
  86
+
70 87
 class TestInlineMedia(TestCase):
71 88
     fixtures = ['admin-views-users.xml']
72 89
 

0 notes on commit dc9d639

Please sign in to comment.
Something went wrong with that request. Please try again.