mirror of
				https://github.com/django/django.git
				synced 2025-11-04 13:39:16 +00:00 
			
		
		
		
	Fixed #11776 -- Added CSS class for non-field/top of form errors.
Thanks Daniel Pope for the suggestion.
This commit is contained in:
		
							parent
							
								
									a00efa30d6
								
							
						
					
					
						commit
						11f0899bbe
					
				
					 10 changed files with 120 additions and 17 deletions
				
			
		
							
								
								
									
										1
									
								
								AUTHORS
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								AUTHORS
									
										
									
									
									
								
							| 
						 | 
					@ -510,6 +510,7 @@ answer newbie questions, and generally made Django that much better:
 | 
				
			||||||
    polpak@yahoo.com
 | 
					    polpak@yahoo.com
 | 
				
			||||||
    Ross Poulton <ross@rossp.org>
 | 
					    Ross Poulton <ross@rossp.org>
 | 
				
			||||||
    Mihai Preda <mihai_preda@yahoo.com>
 | 
					    Mihai Preda <mihai_preda@yahoo.com>
 | 
				
			||||||
 | 
					    Nick Presta <nick@nickpresta.ca>
 | 
				
			||||||
    Matthias Pronk <django@masida.nl>
 | 
					    Matthias Pronk <django@masida.nl>
 | 
				
			||||||
    Jyrki Pulliainen <jyrki.pulliainen@gmail.com>
 | 
					    Jyrki Pulliainen <jyrki.pulliainen@gmail.com>
 | 
				
			||||||
    Thejaswi Puthraya <thejaswi.puthraya@gmail.com>
 | 
					    Thejaswi Puthraya <thejaswi.puthraya@gmail.com>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -280,7 +280,7 @@ class BaseForm(object):
 | 
				
			||||||
        field -- i.e., from Form.clean(). Returns an empty ErrorList if there
 | 
					        field -- i.e., from Form.clean(). Returns an empty ErrorList if there
 | 
				
			||||||
        are none.
 | 
					        are none.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return self.errors.get(NON_FIELD_ERRORS, self.error_class())
 | 
					        return self.errors.get(NON_FIELD_ERRORS, self.error_class(error_class='nonfield'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _raw_value(self, fieldname):
 | 
					    def _raw_value(self, fieldname):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -331,6 +331,9 @@ class BaseForm(object):
 | 
				
			||||||
                if field != NON_FIELD_ERRORS and field not in self.fields:
 | 
					                if field != NON_FIELD_ERRORS and field not in self.fields:
 | 
				
			||||||
                    raise ValueError(
 | 
					                    raise ValueError(
 | 
				
			||||||
                        "'%s' has no field named '%s'." % (self.__class__.__name__, field))
 | 
					                        "'%s' has no field named '%s'." % (self.__class__.__name__, field))
 | 
				
			||||||
 | 
					                if field == NON_FIELD_ERRORS:
 | 
				
			||||||
 | 
					                    self._errors[field] = self.error_class(error_class='nonfield')
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
                    self._errors[field] = self.error_class()
 | 
					                    self._errors[field] = self.error_class()
 | 
				
			||||||
            self._errors[field].extend(error_list)
 | 
					            self._errors[field].extend(error_list)
 | 
				
			||||||
            if field in self.cleaned_data:
 | 
					            if field in self.cleaned_data:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,6 +80,14 @@ class ErrorList(UserList, list):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    A collection of errors that knows how to display itself in various formats.
 | 
					    A collection of errors that knows how to display itself in various formats.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					    def __init__(self, initlist=None, error_class=None):
 | 
				
			||||||
 | 
					        super(ErrorList, self).__init__(initlist)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if error_class is None:
 | 
				
			||||||
 | 
					            self.error_class = 'errorlist'
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.error_class = 'errorlist {}'.format(error_class)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def as_data(self):
 | 
					    def as_data(self):
 | 
				
			||||||
        return ValidationError(self.data).error_list
 | 
					        return ValidationError(self.data).error_list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,8 +107,10 @@ class ErrorList(UserList, list):
 | 
				
			||||||
    def as_ul(self):
 | 
					    def as_ul(self):
 | 
				
			||||||
        if not self.data:
 | 
					        if not self.data:
 | 
				
			||||||
            return ''
 | 
					            return ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return format_html(
 | 
					        return format_html(
 | 
				
			||||||
            '<ul class="errorlist">{0}</ul>',
 | 
					            '<ul class="{0}">{1}</ul>',
 | 
				
			||||||
 | 
					            self.error_class,
 | 
				
			||||||
            format_html_join('', '<li>{0}</li>', ((force_text(e),) for e in self))
 | 
					            format_html_join('', '<li>{0}</li>', ((force_text(e),) for e in self))
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,6 +129,10 @@ Forms
 | 
				
			||||||
  the ``<label>`` tags for required fields will have this class present in its
 | 
					  the ``<label>`` tags for required fields will have this class present in its
 | 
				
			||||||
  attributes.
 | 
					  attributes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* The rendering of non-field errors in unordered lists (``<ul>``) now includes
 | 
				
			||||||
 | 
					  ``nonfield`` in its list of classes to distinguish them from field-specific
 | 
				
			||||||
 | 
					  errors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* :class:`~django.forms.Field` now accepts a
 | 
					* :class:`~django.forms.Field` now accepts a
 | 
				
			||||||
  :attr:`~django.forms.Field.label_suffix` argument, which will override the
 | 
					  :attr:`~django.forms.Field.label_suffix` argument, which will override the
 | 
				
			||||||
  form's :attr:`~django.forms.Form.label_suffix`. This enables customizing the
 | 
					  form's :attr:`~django.forms.Form.label_suffix`. This enables customizing the
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -292,6 +292,17 @@ over them::
 | 
				
			||||||
        </ol>
 | 
					        </ol>
 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. versionchanged:: 1.8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Non-field errors (and/or hidden field errors that are rendered at the top of
 | 
				
			||||||
 | 
					the form when using helpers like ``form.as_p()``) will be rendered with an
 | 
				
			||||||
 | 
					additional class of ``nonfield`` to help distinguish them from field-specific
 | 
				
			||||||
 | 
					errors. For example, ``{{ form.non_field_errors }}`` would look like::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <ul class="errorlist nonfield">
 | 
				
			||||||
 | 
					        <li>Generic validation error</li>
 | 
				
			||||||
 | 
					    </ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Looping over the form's fields
 | 
					Looping over the form's fields
 | 
				
			||||||
------------------------------
 | 
					------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,7 @@ class TestInline(TestCase):
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        response = self.client.post('/admin/admin_inlines/titlecollection/add/', data)
 | 
					        response = self.client.post('/admin/admin_inlines/titlecollection/add/', data)
 | 
				
			||||||
        # Here colspan is "4": two fields (title1 and title2), one hidden field and the delete checkbox.
 | 
					        # Here colspan is "4": two fields (title1 and title2), one hidden field and the delete checkbox.
 | 
				
			||||||
        self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist"><li>The two titles must be the same</li></ul></td></tr>')
 | 
					        self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist nonfield"><li>The two titles must be the same</li></ul></td></tr>')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_no_parent_callable_lookup(self):
 | 
					    def test_no_parent_callable_lookup(self):
 | 
				
			||||||
        """Admin inline `readonly_field` shouldn't invoke parent ModelAdmin callable"""
 | 
					        """Admin inline `readonly_field` shouldn't invoke parent ModelAdmin callable"""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2035,7 +2035,7 @@ class AdminViewListEditable(TestCase):
 | 
				
			||||||
            "_save": "Save",
 | 
					            "_save": "Save",
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        response = self.client.post('/test_admin/admin/admin_views/fooddelivery/', data)
 | 
					        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, html=True)
 | 
					        self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist nonfield"><li>Food delivery with this Driver and Restaurant already exists.</li></ul></td></tr>', 1, html=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        data = {
 | 
					        data = {
 | 
				
			||||||
            "form-TOTAL_FORMS": "3",
 | 
					            "form-TOTAL_FORMS": "3",
 | 
				
			||||||
| 
						 | 
					@ -2062,7 +2062,7 @@ class AdminViewListEditable(TestCase):
 | 
				
			||||||
            "_save": "Save",
 | 
					            "_save": "Save",
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        response = self.client.post('/test_admin/admin/admin_views/fooddelivery/', data)
 | 
					        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, html=True)
 | 
					        self.assertContains(response, '<tr><td colspan="4"><ul class="errorlist nonfield"><li>Food delivery with this Driver and Restaurant already exists.</li></ul></td></tr>', 2, html=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_non_form_errors(self):
 | 
					    def test_non_form_errors(self):
 | 
				
			||||||
        # test if non-form errors are handled; ticket #12716
 | 
					        # test if non-form errors are handled; ticket #12716
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,7 +238,7 @@ class FormsErrorMessagesTestCase(TestCase, AssertFormErrorsMixin):
 | 
				
			||||||
        # This form should print errors the default way.
 | 
					        # This form should print errors the default way.
 | 
				
			||||||
        form1 = TestForm({'first_name': 'John'})
 | 
					        form1 = TestForm({'first_name': 'John'})
 | 
				
			||||||
        self.assertHTMLEqual(str(form1['last_name'].errors), '<ul class="errorlist"><li>This field is required.</li></ul>')
 | 
					        self.assertHTMLEqual(str(form1['last_name'].errors), '<ul class="errorlist"><li>This field is required.</li></ul>')
 | 
				
			||||||
        self.assertHTMLEqual(str(form1.errors['__all__']), '<ul class="errorlist"><li>I like to be awkward.</li></ul>')
 | 
					        self.assertHTMLEqual(str(form1.errors['__all__']), '<ul class="errorlist nonfield"><li>I like to be awkward.</li></ul>')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # This one should wrap error groups in the customized way.
 | 
					        # This one should wrap error groups in the customized way.
 | 
				
			||||||
        form2 = TestForm({'first_name': 'John'}, error_class=CustomErrorList)
 | 
					        form2 = TestForm({'first_name': 'John'}, error_class=CustomErrorList)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -713,11 +713,11 @@ class FormsTestCase(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
 | 
					        f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
 | 
				
			||||||
        self.assertEqual(f.errors['__all__'], ['Please make sure your passwords match.'])
 | 
					        self.assertEqual(f.errors['__all__'], ['Please make sure your passwords match.'])
 | 
				
			||||||
        self.assertHTMLEqual(f.as_table(), """<tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
 | 
					        self.assertHTMLEqual(f.as_table(), """<tr><td colspan="2"><ul class="errorlist nonfield"><li>Please make sure your passwords match.</li></ul></td></tr>
 | 
				
			||||||
<tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr>
 | 
					<tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr>
 | 
				
			||||||
<tr><th>Password1:</th><td><input type="password" name="password1" /></td></tr>
 | 
					<tr><th>Password1:</th><td><input type="password" name="password1" /></td></tr>
 | 
				
			||||||
<tr><th>Password2:</th><td><input type="password" name="password2" /></td></tr>""")
 | 
					<tr><th>Password2:</th><td><input type="password" name="password2" /></td></tr>""")
 | 
				
			||||||
        self.assertHTMLEqual(f.as_ul(), """<li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></li>
 | 
					        self.assertHTMLEqual(f.as_ul(), """<li><ul class="errorlist nonfield"><li>Please make sure your passwords match.</li></ul></li>
 | 
				
			||||||
<li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li>
 | 
					<li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li>
 | 
				
			||||||
<li>Password1: <input type="password" name="password1" /></li>
 | 
					<li>Password1: <input type="password" name="password1" /></li>
 | 
				
			||||||
<li>Password2: <input type="password" name="password2" /></li>""")
 | 
					<li>Password2: <input type="password" name="password2" /></li>""")
 | 
				
			||||||
| 
						 | 
					@ -947,15 +947,15 @@ class FormsTestCase(TestCase):
 | 
				
			||||||
        # prepended. This message is displayed at the top of the output, regardless of
 | 
					        # prepended. This message is displayed at the top of the output, regardless of
 | 
				
			||||||
        # its field's order in the form.
 | 
					        # its field's order in the form.
 | 
				
			||||||
        p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}, auto_id=False)
 | 
					        p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}, auto_id=False)
 | 
				
			||||||
        self.assertHTMLEqual(p.as_table(), """<tr><td colspan="2"><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></td></tr>
 | 
					        self.assertHTMLEqual(p.as_table(), """<tr><td colspan="2"><ul class="errorlist nonfield"><li>(Hidden field hidden_text) This field is required.</li></ul></td></tr>
 | 
				
			||||||
<tr><th>First name:</th><td><input type="text" name="first_name" value="John" /></td></tr>
 | 
					<tr><th>First name:</th><td><input type="text" name="first_name" value="John" /></td></tr>
 | 
				
			||||||
<tr><th>Last name:</th><td><input type="text" name="last_name" value="Lennon" /></td></tr>
 | 
					<tr><th>Last name:</th><td><input type="text" name="last_name" value="Lennon" /></td></tr>
 | 
				
			||||||
<tr><th>Birthday:</th><td><input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></td></tr>""")
 | 
					<tr><th>Birthday:</th><td><input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></td></tr>""")
 | 
				
			||||||
        self.assertHTMLEqual(p.as_ul(), """<li><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></li>
 | 
					        self.assertHTMLEqual(p.as_ul(), """<li><ul class="errorlist nonfield"><li>(Hidden field hidden_text) This field is required.</li></ul></li>
 | 
				
			||||||
<li>First name: <input type="text" name="first_name" value="John" /></li>
 | 
					<li>First name: <input type="text" name="first_name" value="John" /></li>
 | 
				
			||||||
<li>Last name: <input type="text" name="last_name" value="Lennon" /></li>
 | 
					<li>Last name: <input type="text" name="last_name" value="Lennon" /></li>
 | 
				
			||||||
<li>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></li>""")
 | 
					<li>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></li>""")
 | 
				
			||||||
        self.assertHTMLEqual(p.as_p(), """<ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul>
 | 
					        self.assertHTMLEqual(p.as_p(), """<ul class="errorlist nonfield"><li>(Hidden field hidden_text) This field is required.</li></ul>
 | 
				
			||||||
<p>First name: <input type="text" name="first_name" value="John" /></p>
 | 
					<p>First name: <input type="text" name="first_name" value="John" /></p>
 | 
				
			||||||
<p>Last name: <input type="text" name="last_name" value="Lennon" /></p>
 | 
					<p>Last name: <input type="text" name="last_name" value="Lennon" /></p>
 | 
				
			||||||
<p>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></p>""")
 | 
					<p>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></p>""")
 | 
				
			||||||
| 
						 | 
					@ -1637,7 +1637,7 @@ class FormsTestCase(TestCase):
 | 
				
			||||||
        # Case 2: POST with erroneous data (a redisplayed form, with errors).)
 | 
					        # Case 2: POST with erroneous data (a redisplayed form, with errors).)
 | 
				
			||||||
        self.assertHTMLEqual(my_function('POST', {'username': 'this-is-a-long-username', 'password1': 'foo', 'password2': 'bar'}), """<form action="" method="post">
 | 
					        self.assertHTMLEqual(my_function('POST', {'username': 'this-is-a-long-username', 'password1': 'foo', 'password2': 'bar'}), """<form action="" method="post">
 | 
				
			||||||
<table>
 | 
					<table>
 | 
				
			||||||
<tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
 | 
					<tr><td colspan="2"><ul class="errorlist nonfield"><li>Please make sure your passwords match.</li></ul></td></tr>
 | 
				
			||||||
<tr><th>Username:</th><td><ul class="errorlist"><li>Ensure this value has at most 10 characters (it has 23).</li></ul><input type="text" name="username" value="this-is-a-long-username" maxlength="10" /></td></tr>
 | 
					<tr><th>Username:</th><td><ul class="errorlist"><li>Ensure this value has at most 10 characters (it has 23).</li></ul><input type="text" name="username" value="this-is-a-long-username" maxlength="10" /></td></tr>
 | 
				
			||||||
<tr><th>Password1:</th><td><input type="password" name="password1" /></td></tr>
 | 
					<tr><th>Password1:</th><td><input type="password" name="password1" /></td></tr>
 | 
				
			||||||
<tr><th>Password2:</th><td><input type="password" name="password2" /></td></tr>
 | 
					<tr><th>Password2:</th><td><input type="password" name="password2" /></td></tr>
 | 
				
			||||||
| 
						 | 
					@ -1764,7 +1764,7 @@ class FormsTestCase(TestCase):
 | 
				
			||||||
<input type="submit" />
 | 
					<input type="submit" />
 | 
				
			||||||
</form>''')
 | 
					</form>''')
 | 
				
			||||||
        self.assertHTMLEqual(t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)})), """<form action="">
 | 
					        self.assertHTMLEqual(t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)})), """<form action="">
 | 
				
			||||||
<ul class="errorlist"><li>Please make sure your passwords match.</li></ul>
 | 
					<ul class="errorlist nonfield"><li>Please make sure your passwords match.</li></ul>
 | 
				
			||||||
<p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p>
 | 
					<p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p>
 | 
				
			||||||
<p><label>Password: <input type="password" name="password1" /></label></p>
 | 
					<p><label>Password: <input type="password" name="password1" /></label></p>
 | 
				
			||||||
<p><label>Password (again): <input type="password" name="password2" /></label></p>
 | 
					<p><label>Password (again): <input type="password" name="password2" /></label></p>
 | 
				
			||||||
| 
						 | 
					@ -2137,7 +2137,7 @@ class FormsTestCase(TestCase):
 | 
				
			||||||
        control = [
 | 
					        control = [
 | 
				
			||||||
            '<li>foo<ul class="errorlist"><li>This field is required.</li></ul></li>',
 | 
					            '<li>foo<ul class="errorlist"><li>This field is required.</li></ul></li>',
 | 
				
			||||||
            '<li>bar<ul class="errorlist"><li>This field is required.</li></ul></li>',
 | 
					            '<li>bar<ul class="errorlist"><li>This field is required.</li></ul></li>',
 | 
				
			||||||
            '<li>__all__<ul class="errorlist"><li>Non-field error.</li></ul></li>',
 | 
					            '<li>__all__<ul class="errorlist nonfield"><li>Non-field error.</li></ul></li>',
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
        for error in control:
 | 
					        for error in control:
 | 
				
			||||||
            self.assertInHTML(error, errors)
 | 
					            self.assertInHTML(error, errors)
 | 
				
			||||||
| 
						 | 
					@ -2200,3 +2200,77 @@ class FormsTestCase(TestCase):
 | 
				
			||||||
            json.loads(e.as_json()),
 | 
					            json.loads(e.as_json()),
 | 
				
			||||||
            [{"message": "Foo", "code": ""}, {"message": "Foobar", "code": "foobar"}]
 | 
					            [{"message": "Foo", "code": ""}, {"message": "Foobar", "code": "foobar"}]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_error_list_class_not_specified(self):
 | 
				
			||||||
 | 
					        e = ErrorList()
 | 
				
			||||||
 | 
					        e.append('Foo')
 | 
				
			||||||
 | 
					        e.append(ValidationError('Foo%(bar)s', code='foobar', params={'bar': 'bar'}))
 | 
				
			||||||
 | 
					        self.assertEqual(
 | 
				
			||||||
 | 
					            e.as_ul(),
 | 
				
			||||||
 | 
					            '<ul class="errorlist"><li>Foo</li><li>Foobar</li></ul>'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_error_list_class_has_one_class_specified(self):
 | 
				
			||||||
 | 
					        e = ErrorList(error_class='foobar-error-class')
 | 
				
			||||||
 | 
					        e.append('Foo')
 | 
				
			||||||
 | 
					        e.append(ValidationError('Foo%(bar)s', code='foobar', params={'bar': 'bar'}))
 | 
				
			||||||
 | 
					        self.assertEqual(
 | 
				
			||||||
 | 
					            e.as_ul(),
 | 
				
			||||||
 | 
					            '<ul class="errorlist foobar-error-class"><li>Foo</li><li>Foobar</li></ul>'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_error_list_with_hidden_field_errors_has_correct_class(self):
 | 
				
			||||||
 | 
					        class Person(Form):
 | 
				
			||||||
 | 
					            first_name = CharField()
 | 
				
			||||||
 | 
					            last_name = CharField(widget=HiddenInput)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        p = Person({'first_name': 'John'})
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            p.as_ul(),
 | 
				
			||||||
 | 
					            """<li><ul class="errorlist nonfield"><li>(Hidden field last_name) This field is required.</li></ul></li><li><label for="id_first_name">First name:</label> <input id="id_first_name" name="first_name" type="text" value="John" /><input id="id_last_name" name="last_name" type="hidden" /></li>"""
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            p.as_p(),
 | 
				
			||||||
 | 
					            """<ul class="errorlist nonfield"><li>(Hidden field last_name) This field is required.</li></ul>
 | 
				
			||||||
 | 
					<p><label for="id_first_name">First name:</label> <input id="id_first_name" name="first_name" type="text" value="John" /><input id="id_last_name" name="last_name" type="hidden" /></p>"""
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            p.as_table(),
 | 
				
			||||||
 | 
					            """<tr><td colspan="2"><ul class="errorlist nonfield"><li>(Hidden field last_name) This field is required.</li></ul></td></tr>
 | 
				
			||||||
 | 
					<tr><th><label for="id_first_name">First name:</label></th><td><input id="id_first_name" name="first_name" type="text" value="John" /><input id="id_last_name" name="last_name" type="hidden" /></td></tr>"""
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_error_list_with_non_field_errors_has_correct_class(self):
 | 
				
			||||||
 | 
					        class Person(Form):
 | 
				
			||||||
 | 
					            first_name = CharField()
 | 
				
			||||||
 | 
					            last_name = CharField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def clean(self):
 | 
				
			||||||
 | 
					                raise ValidationError('Generic validation error')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        p = Person({'first_name': 'John', 'last_name': 'Lennon'})
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            str(p.non_field_errors()),
 | 
				
			||||||
 | 
					            '<ul class="errorlist nonfield"><li>Generic validation error</li></ul>'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            p.as_ul(),
 | 
				
			||||||
 | 
					            """<li><ul class="errorlist nonfield"><li>Generic validation error</li></ul></li><li><label for="id_first_name">First name:</label> <input id="id_first_name" name="first_name" type="text" value="John" /></li>
 | 
				
			||||||
 | 
					<li><label for="id_last_name">Last name:</label> <input id="id_last_name" name="last_name" type="text" value="Lennon" /></li>"""
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            p.non_field_errors().as_text(),
 | 
				
			||||||
 | 
					            '* Generic validation error'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            p.as_p(),
 | 
				
			||||||
 | 
					            """<ul class="errorlist nonfield"><li>Generic validation error</li></ul>
 | 
				
			||||||
 | 
					<p><label for="id_first_name">First name:</label> <input id="id_first_name" name="first_name" type="text" value="John" /></p>
 | 
				
			||||||
 | 
					<p><label for="id_last_name">Last name:</label> <input id="id_last_name" name="last_name" type="text" value="Lennon" /></p>"""
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            p.as_table(),
 | 
				
			||||||
 | 
					            """<tr><td colspan="2"><ul class="errorlist nonfield"><li>Generic validation error</li></ul></td></tr>
 | 
				
			||||||
 | 
					<tr><th><label for="id_first_name">First name:</label></th><td><input id="id_first_name" name="first_name" type="text" value="John" /></td></tr>
 | 
				
			||||||
 | 
					<tr><th><label for="id_last_name">Last name:</label></th><td><input id="id_last_name" name="last_name" type="text" value="Lennon" /></td></tr>"""
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,8 +98,8 @@ class FormsRegressionsTestCase(TestCase):
 | 
				
			||||||
            data = IntegerField(widget=HiddenInput)
 | 
					            data = IntegerField(widget=HiddenInput)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        f = HiddenForm({})
 | 
					        f = HiddenForm({})
 | 
				
			||||||
        self.assertHTMLEqual(f.as_p(), '<ul class="errorlist"><li>(Hidden field data) This field is required.</li></ul>\n<p> <input type="hidden" name="data" id="id_data" /></p>')
 | 
					        self.assertHTMLEqual(f.as_p(), '<ul class="errorlist nonfield"><li>(Hidden field data) This field is required.</li></ul>\n<p> <input type="hidden" name="data" id="id_data" /></p>')
 | 
				
			||||||
        self.assertHTMLEqual(f.as_table(), '<tr><td colspan="2"><ul class="errorlist"><li>(Hidden field data) This field is required.</li></ul><input type="hidden" name="data" id="id_data" /></td></tr>')
 | 
					        self.assertHTMLEqual(f.as_table(), '<tr><td colspan="2"><ul class="errorlist nonfield"><li>(Hidden field data) This field is required.</li></ul><input type="hidden" name="data" id="id_data" /></td></tr>')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_xss_error_messages(self):
 | 
					    def test_xss_error_messages(self):
 | 
				
			||||||
        ###################################################
 | 
					        ###################################################
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue