Ticket #13510: 13510_tabular_inline_errors_colspan.diff

File 13510_tabular_inline_errors_colspan.diff, 5.0 KB (added by julien, 4 years ago)
  • django/contrib/admin/templates/admin/edit_inline/tabular.html

    diff --git a/django/contrib/admin/templates/admin/edit_inline/tabular.html b/django/contrib/admin/templates/admin/edit_inline/tabular.html
    index a5b1a89..7f6c34a 100644
    a b  
    1 {% load i18n adminmedia %}
     1{% load i18n adminmedia admin_modify %}
    22<div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group">
    33  <div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
    44{{ inline_admin_formset.formset.management_form }}
     
    1818     <tbody>
    1919     {% for inline_admin_form in inline_admin_formset %}
    2020        {% 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>
    2222        {% endif %}
    2323        <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 %}"
    2424             id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
  • django/contrib/admin/templatetags/admin_modify.py

    diff --git a/django/contrib/admin/templatetags/admin_modify.py b/django/contrib/admin/templatetags/admin_modify.py
    index fe88043..5c00de3 100644
    a b def submit_row(context): 
    4040        'show_save': True
    4141    }
    4242submit_row = register.inclusion_tag('admin/submit_line.html', takes_context=True)(submit_row)
     43
     44def 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
     56cell_count = register.filter(cell_count)
  • tests/regressiontests/admin_inlines/models.py

    diff --git a/tests/regressiontests/admin_inlines/models.py b/tests/regressiontests/admin_inlines/models.py
    index 4e5c4e3..772152a 100644
    a b from django.db import models 
    66from django.contrib import admin
    77from django.contrib.contenttypes.models import ContentType
    88from django.contrib.contenttypes import generic
     9from django import forms
    910
    1011class Parent(models.Model):
    1112    name = models.CharField(max_length=50)
    class InlineWeakness(admin.TabularInline): 
    123124    extra = 1
    124125
    125126admin.site.register(Fashionista, inlines=[InlineWeakness])
     127
     128
     129# Models for #13510 --------------------
     130
     131class TitleCollection(models.Model):
     132    pass
     133   
     134class Title(models.Model):
     135    collection = models.ForeignKey(TitleCollection, blank=True, null=True)
     136    title1 = models.CharField(max_length=100)
     137    title2 = models.CharField(max_length=100)
     138   
     139class TitleForm(forms.ModelForm):
     140   
     141    def clean(self):
     142        cleaned_data = self.cleaned_data
     143        title1 = cleaned_data.get("title1")
     144        title2 = cleaned_data.get("title2")
     145        if title1 != title2:
     146            raise forms.ValidationError("The two titles must be the same")
     147        return cleaned_data
     148
     149class TitleInline(admin.TabularInline):
     150    model = Title
     151    form = TitleForm
     152    extra = 1
     153
     154admin.site.register(TitleCollection, inlines=[TitleInline])
  • tests/regressiontests/admin_inlines/tests.py

    diff --git a/tests/regressiontests/admin_inlines/tests.py b/tests/regressiontests/admin_inlines/tests.py
    index b10474d..69ff96c 100644
    a b class TestInline(TestCase): 
    6767        self.assertEqual(response.status_code, 302)
    6868        self.assertEqual(len(Fashionista.objects.filter(person__firstname='Imelda')), 1)
    6969
     70    def test_tabular_non_field_errors(self):
     71        """ Ensure that non_field_errors are displayed correctly, including
     72            the right value for colspan.
     73            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       
    7087class TestInlineMedia(TestCase):
    7188    fixtures = ['admin-views-users.xml']
    7289
Back to Top