mirror of
				https://github.com/django/django.git
				synced 2025-11-04 05:35:37 +00:00 
			
		
		
		
	Cleaned up some forms tests.
Thanks Berker Peksag and Tim Graham for the reviews. Refs #24219.
This commit is contained in:
		
							parent
							
								
									84b6c76830
								
							
						
					
					
						commit
						3a4c9e1b43
					
				
					 5 changed files with 969 additions and 883 deletions
				
			
		| 
						 | 
					@ -1,844 +0,0 @@
 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					 | 
				
			||||||
from __future__ import unicode_literals
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import datetime
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from django.forms import (
 | 
					 | 
				
			||||||
    CharField, DateField, EmailField, FileField, Form, GenericIPAddressField,
 | 
					 | 
				
			||||||
    HiddenInput, ImageField, MultipleChoiceField, MultiValueField, MultiWidget,
 | 
					 | 
				
			||||||
    PasswordInput, SelectMultiple, SlugField, SplitDateTimeField,
 | 
					 | 
				
			||||||
    SplitDateTimeWidget, TextInput, URLField,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
from django.forms.extras import SelectDateWidget
 | 
					 | 
				
			||||||
from django.forms.utils import ErrorList
 | 
					 | 
				
			||||||
from django.test import TestCase, override_settings
 | 
					 | 
				
			||||||
from django.utils import six
 | 
					 | 
				
			||||||
from django.utils import translation
 | 
					 | 
				
			||||||
from django.utils.dates import MONTHS_AP
 | 
					 | 
				
			||||||
from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from .test_error_messages import AssertFormErrorsMixin
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class GetDate(Form):
 | 
					 | 
				
			||||||
    mydate = DateField(widget=SelectDateWidget)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class GetDateShowHiddenInitial(Form):
 | 
					 | 
				
			||||||
    mydate = DateField(widget=SelectDateWidget, show_hidden_initial=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
 | 
					 | 
				
			||||||
    ###############
 | 
					 | 
				
			||||||
    # Extra stuff #
 | 
					 | 
				
			||||||
    ###############
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # The forms library comes with some extra, higher-level Field and Widget
 | 
					 | 
				
			||||||
    def test_selectdate(self):
 | 
					 | 
				
			||||||
        self.maxDiff = None
 | 
					 | 
				
			||||||
        w = SelectDateWidget(years=('2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Rendering the default state.
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="1">January</option>
 | 
					 | 
				
			||||||
<option value="2">February</option>
 | 
					 | 
				
			||||||
<option value="3">March</option>
 | 
					 | 
				
			||||||
<option value="4">April</option>
 | 
					 | 
				
			||||||
<option value="5">May</option>
 | 
					 | 
				
			||||||
<option value="6">June</option>
 | 
					 | 
				
			||||||
<option value="7">July</option>
 | 
					 | 
				
			||||||
<option value="8">August</option>
 | 
					 | 
				
			||||||
<option value="9">September</option>
 | 
					 | 
				
			||||||
<option value="10">October</option>
 | 
					 | 
				
			||||||
<option value="11">November</option>
 | 
					 | 
				
			||||||
<option value="12">December</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<select name="mydate_day" id="id_mydate_day">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="1">1</option>
 | 
					 | 
				
			||||||
<option value="2">2</option>
 | 
					 | 
				
			||||||
<option value="3">3</option>
 | 
					 | 
				
			||||||
<option value="4">4</option>
 | 
					 | 
				
			||||||
<option value="5">5</option>
 | 
					 | 
				
			||||||
<option value="6">6</option>
 | 
					 | 
				
			||||||
<option value="7">7</option>
 | 
					 | 
				
			||||||
<option value="8">8</option>
 | 
					 | 
				
			||||||
<option value="9">9</option>
 | 
					 | 
				
			||||||
<option value="10">10</option>
 | 
					 | 
				
			||||||
<option value="11">11</option>
 | 
					 | 
				
			||||||
<option value="12">12</option>
 | 
					 | 
				
			||||||
<option value="13">13</option>
 | 
					 | 
				
			||||||
<option value="14">14</option>
 | 
					 | 
				
			||||||
<option value="15">15</option>
 | 
					 | 
				
			||||||
<option value="16">16</option>
 | 
					 | 
				
			||||||
<option value="17">17</option>
 | 
					 | 
				
			||||||
<option value="18">18</option>
 | 
					 | 
				
			||||||
<option value="19">19</option>
 | 
					 | 
				
			||||||
<option value="20">20</option>
 | 
					 | 
				
			||||||
<option value="21">21</option>
 | 
					 | 
				
			||||||
<option value="22">22</option>
 | 
					 | 
				
			||||||
<option value="23">23</option>
 | 
					 | 
				
			||||||
<option value="24">24</option>
 | 
					 | 
				
			||||||
<option value="25">25</option>
 | 
					 | 
				
			||||||
<option value="26">26</option>
 | 
					 | 
				
			||||||
<option value="27">27</option>
 | 
					 | 
				
			||||||
<option value="28">28</option>
 | 
					 | 
				
			||||||
<option value="29">29</option>
 | 
					 | 
				
			||||||
<option value="30">30</option>
 | 
					 | 
				
			||||||
<option value="31">31</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<select name="mydate_year" id="id_mydate_year">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="2007">2007</option>
 | 
					 | 
				
			||||||
<option value="2008">2008</option>
 | 
					 | 
				
			||||||
<option value="2009">2009</option>
 | 
					 | 
				
			||||||
<option value="2010">2010</option>
 | 
					 | 
				
			||||||
<option value="2011">2011</option>
 | 
					 | 
				
			||||||
<option value="2012">2012</option>
 | 
					 | 
				
			||||||
<option value="2013">2013</option>
 | 
					 | 
				
			||||||
<option value="2014">2014</option>
 | 
					 | 
				
			||||||
<option value="2015">2015</option>
 | 
					 | 
				
			||||||
<option value="2016">2016</option>
 | 
					 | 
				
			||||||
</select>""")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Rendering the None or '' values should yield the same output.
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(w.render('mydate', None), w.render('mydate', ''))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Rendering a string value.
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="1">January</option>
 | 
					 | 
				
			||||||
<option value="2">February</option>
 | 
					 | 
				
			||||||
<option value="3">March</option>
 | 
					 | 
				
			||||||
<option value="4" selected="selected">April</option>
 | 
					 | 
				
			||||||
<option value="5">May</option>
 | 
					 | 
				
			||||||
<option value="6">June</option>
 | 
					 | 
				
			||||||
<option value="7">July</option>
 | 
					 | 
				
			||||||
<option value="8">August</option>
 | 
					 | 
				
			||||||
<option value="9">September</option>
 | 
					 | 
				
			||||||
<option value="10">October</option>
 | 
					 | 
				
			||||||
<option value="11">November</option>
 | 
					 | 
				
			||||||
<option value="12">December</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<select name="mydate_day" id="id_mydate_day">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="1">1</option>
 | 
					 | 
				
			||||||
<option value="2">2</option>
 | 
					 | 
				
			||||||
<option value="3">3</option>
 | 
					 | 
				
			||||||
<option value="4">4</option>
 | 
					 | 
				
			||||||
<option value="5">5</option>
 | 
					 | 
				
			||||||
<option value="6">6</option>
 | 
					 | 
				
			||||||
<option value="7">7</option>
 | 
					 | 
				
			||||||
<option value="8">8</option>
 | 
					 | 
				
			||||||
<option value="9">9</option>
 | 
					 | 
				
			||||||
<option value="10">10</option>
 | 
					 | 
				
			||||||
<option value="11">11</option>
 | 
					 | 
				
			||||||
<option value="12">12</option>
 | 
					 | 
				
			||||||
<option value="13">13</option>
 | 
					 | 
				
			||||||
<option value="14">14</option>
 | 
					 | 
				
			||||||
<option value="15" selected="selected">15</option>
 | 
					 | 
				
			||||||
<option value="16">16</option>
 | 
					 | 
				
			||||||
<option value="17">17</option>
 | 
					 | 
				
			||||||
<option value="18">18</option>
 | 
					 | 
				
			||||||
<option value="19">19</option>
 | 
					 | 
				
			||||||
<option value="20">20</option>
 | 
					 | 
				
			||||||
<option value="21">21</option>
 | 
					 | 
				
			||||||
<option value="22">22</option>
 | 
					 | 
				
			||||||
<option value="23">23</option>
 | 
					 | 
				
			||||||
<option value="24">24</option>
 | 
					 | 
				
			||||||
<option value="25">25</option>
 | 
					 | 
				
			||||||
<option value="26">26</option>
 | 
					 | 
				
			||||||
<option value="27">27</option>
 | 
					 | 
				
			||||||
<option value="28">28</option>
 | 
					 | 
				
			||||||
<option value="29">29</option>
 | 
					 | 
				
			||||||
<option value="30">30</option>
 | 
					 | 
				
			||||||
<option value="31">31</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<select name="mydate_year" id="id_mydate_year">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="2007">2007</option>
 | 
					 | 
				
			||||||
<option value="2008">2008</option>
 | 
					 | 
				
			||||||
<option value="2009">2009</option>
 | 
					 | 
				
			||||||
<option value="2010" selected="selected">2010</option>
 | 
					 | 
				
			||||||
<option value="2011">2011</option>
 | 
					 | 
				
			||||||
<option value="2012">2012</option>
 | 
					 | 
				
			||||||
<option value="2013">2013</option>
 | 
					 | 
				
			||||||
<option value="2014">2014</option>
 | 
					 | 
				
			||||||
<option value="2015">2015</option>
 | 
					 | 
				
			||||||
<option value="2016">2016</option>
 | 
					 | 
				
			||||||
</select>""")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Rendering a datetime value.
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(w.render('mydate', datetime.date(2010, 4, 15)), w.render('mydate', '2010-04-15'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Invalid dates should still render the failed date.
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(w.render('mydate', '2010-02-31'), """<select name="mydate_month" id="id_mydate_month">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="1">January</option>
 | 
					 | 
				
			||||||
<option value="2" selected="selected">February</option>
 | 
					 | 
				
			||||||
<option value="3">March</option>
 | 
					 | 
				
			||||||
<option value="4">April</option>
 | 
					 | 
				
			||||||
<option value="5">May</option>
 | 
					 | 
				
			||||||
<option value="6">June</option>
 | 
					 | 
				
			||||||
<option value="7">July</option>
 | 
					 | 
				
			||||||
<option value="8">August</option>
 | 
					 | 
				
			||||||
<option value="9">September</option>
 | 
					 | 
				
			||||||
<option value="10">October</option>
 | 
					 | 
				
			||||||
<option value="11">November</option>
 | 
					 | 
				
			||||||
<option value="12">December</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<select name="mydate_day" id="id_mydate_day">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="1">1</option>
 | 
					 | 
				
			||||||
<option value="2">2</option>
 | 
					 | 
				
			||||||
<option value="3">3</option>
 | 
					 | 
				
			||||||
<option value="4">4</option>
 | 
					 | 
				
			||||||
<option value="5">5</option>
 | 
					 | 
				
			||||||
<option value="6">6</option>
 | 
					 | 
				
			||||||
<option value="7">7</option>
 | 
					 | 
				
			||||||
<option value="8">8</option>
 | 
					 | 
				
			||||||
<option value="9">9</option>
 | 
					 | 
				
			||||||
<option value="10">10</option>
 | 
					 | 
				
			||||||
<option value="11">11</option>
 | 
					 | 
				
			||||||
<option value="12">12</option>
 | 
					 | 
				
			||||||
<option value="13">13</option>
 | 
					 | 
				
			||||||
<option value="14">14</option>
 | 
					 | 
				
			||||||
<option value="15">15</option>
 | 
					 | 
				
			||||||
<option value="16">16</option>
 | 
					 | 
				
			||||||
<option value="17">17</option>
 | 
					 | 
				
			||||||
<option value="18">18</option>
 | 
					 | 
				
			||||||
<option value="19">19</option>
 | 
					 | 
				
			||||||
<option value="20">20</option>
 | 
					 | 
				
			||||||
<option value="21">21</option>
 | 
					 | 
				
			||||||
<option value="22">22</option>
 | 
					 | 
				
			||||||
<option value="23">23</option>
 | 
					 | 
				
			||||||
<option value="24">24</option>
 | 
					 | 
				
			||||||
<option value="25">25</option>
 | 
					 | 
				
			||||||
<option value="26">26</option>
 | 
					 | 
				
			||||||
<option value="27">27</option>
 | 
					 | 
				
			||||||
<option value="28">28</option>
 | 
					 | 
				
			||||||
<option value="29">29</option>
 | 
					 | 
				
			||||||
<option value="30">30</option>
 | 
					 | 
				
			||||||
<option value="31" selected="selected">31</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<select name="mydate_year" id="id_mydate_year">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="2007">2007</option>
 | 
					 | 
				
			||||||
<option value="2008">2008</option>
 | 
					 | 
				
			||||||
<option value="2009">2009</option>
 | 
					 | 
				
			||||||
<option value="2010" selected="selected">2010</option>
 | 
					 | 
				
			||||||
<option value="2011">2011</option>
 | 
					 | 
				
			||||||
<option value="2012">2012</option>
 | 
					 | 
				
			||||||
<option value="2013">2013</option>
 | 
					 | 
				
			||||||
<option value="2014">2014</option>
 | 
					 | 
				
			||||||
<option value="2015">2015</option>
 | 
					 | 
				
			||||||
<option value="2016">2016</option>
 | 
					 | 
				
			||||||
</select>""")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Rendering with a custom months dict.
 | 
					 | 
				
			||||||
        w = SelectDateWidget(months=MONTHS_AP, years=('2013',))
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="1">Jan.</option>
 | 
					 | 
				
			||||||
<option value="2">Feb.</option>
 | 
					 | 
				
			||||||
<option value="3">March</option>
 | 
					 | 
				
			||||||
<option value="4">April</option>
 | 
					 | 
				
			||||||
<option value="5">May</option>
 | 
					 | 
				
			||||||
<option value="6">June</option>
 | 
					 | 
				
			||||||
<option value="7">July</option>
 | 
					 | 
				
			||||||
<option value="8">Aug.</option>
 | 
					 | 
				
			||||||
<option value="9">Sept.</option>
 | 
					 | 
				
			||||||
<option value="10">Oct.</option>
 | 
					 | 
				
			||||||
<option value="11">Nov.</option>
 | 
					 | 
				
			||||||
<option value="12">Dec.</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<select name="mydate_day" id="id_mydate_day">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="1">1</option>
 | 
					 | 
				
			||||||
<option value="2">2</option>
 | 
					 | 
				
			||||||
<option value="3">3</option>
 | 
					 | 
				
			||||||
<option value="4">4</option>
 | 
					 | 
				
			||||||
<option value="5">5</option>
 | 
					 | 
				
			||||||
<option value="6">6</option>
 | 
					 | 
				
			||||||
<option value="7">7</option>
 | 
					 | 
				
			||||||
<option value="8">8</option>
 | 
					 | 
				
			||||||
<option value="9">9</option>
 | 
					 | 
				
			||||||
<option value="10">10</option>
 | 
					 | 
				
			||||||
<option value="11">11</option>
 | 
					 | 
				
			||||||
<option value="12">12</option>
 | 
					 | 
				
			||||||
<option value="13">13</option>
 | 
					 | 
				
			||||||
<option value="14">14</option>
 | 
					 | 
				
			||||||
<option value="15">15</option>
 | 
					 | 
				
			||||||
<option value="16">16</option>
 | 
					 | 
				
			||||||
<option value="17">17</option>
 | 
					 | 
				
			||||||
<option value="18">18</option>
 | 
					 | 
				
			||||||
<option value="19">19</option>
 | 
					 | 
				
			||||||
<option value="20">20</option>
 | 
					 | 
				
			||||||
<option value="21">21</option>
 | 
					 | 
				
			||||||
<option value="22">22</option>
 | 
					 | 
				
			||||||
<option value="23">23</option>
 | 
					 | 
				
			||||||
<option value="24">24</option>
 | 
					 | 
				
			||||||
<option value="25">25</option>
 | 
					 | 
				
			||||||
<option value="26">26</option>
 | 
					 | 
				
			||||||
<option value="27">27</option>
 | 
					 | 
				
			||||||
<option value="28">28</option>
 | 
					 | 
				
			||||||
<option value="29">29</option>
 | 
					 | 
				
			||||||
<option value="30">30</option>
 | 
					 | 
				
			||||||
<option value="31">31</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<select name="mydate_year" id="id_mydate_year">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="2013">2013</option>
 | 
					 | 
				
			||||||
</select>""")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        a = GetDate({'mydate_month': '4', 'mydate_day': '1', 'mydate_year': '2008'})
 | 
					 | 
				
			||||||
        self.assertTrue(a.is_valid())
 | 
					 | 
				
			||||||
        self.assertEqual(a.cleaned_data['mydate'], datetime.date(2008, 4, 1))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # As with any widget that implements get_value_from_datadict,
 | 
					 | 
				
			||||||
        # we must be prepared to accept the input from the "as_hidden"
 | 
					 | 
				
			||||||
        # rendering as well.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(a['mydate'].as_hidden(), '<input type="hidden" name="mydate" value="2008-4-1" id="id_mydate" />')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        b = GetDate({'mydate': '2008-4-1'})
 | 
					 | 
				
			||||||
        self.assertTrue(b.is_valid())
 | 
					 | 
				
			||||||
        self.assertEqual(b.cleaned_data['mydate'], datetime.date(2008, 4, 1))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Invalid dates shouldn't be allowed
 | 
					 | 
				
			||||||
        c = GetDate({'mydate_month': '2', 'mydate_day': '31', 'mydate_year': '2010'})
 | 
					 | 
				
			||||||
        self.assertFalse(c.is_valid())
 | 
					 | 
				
			||||||
        self.assertEqual(c.errors, {'mydate': ['Enter a valid date.']})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # label tag is correctly associated with month dropdown
 | 
					 | 
				
			||||||
        d = GetDate({'mydate_month': '1', 'mydate_day': '1', 'mydate_year': '2010'})
 | 
					 | 
				
			||||||
        self.assertIn('<label for="id_mydate_month">', d.as_p())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_selectdate_empty_label(self):
 | 
					 | 
				
			||||||
        w = SelectDateWidget(years=('2014',), empty_label='empty_label')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Rendering the default state with empty_label setted as string.
 | 
					 | 
				
			||||||
        self.assertInHTML('<option value="0">empty_label</option>', w.render('mydate', ''), count=3)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        w = SelectDateWidget(years=('2014',), empty_label=('empty_year', 'empty_month', 'empty_day'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Rendering the default state with empty_label tuple.
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
 | 
					 | 
				
			||||||
<option value="0">empty_month</option>
 | 
					 | 
				
			||||||
<option value="1">January</option>
 | 
					 | 
				
			||||||
<option value="2">February</option>
 | 
					 | 
				
			||||||
<option value="3">March</option>
 | 
					 | 
				
			||||||
<option value="4">April</option>
 | 
					 | 
				
			||||||
<option value="5">May</option>
 | 
					 | 
				
			||||||
<option value="6">June</option>
 | 
					 | 
				
			||||||
<option value="7">July</option>
 | 
					 | 
				
			||||||
<option value="8">August</option>
 | 
					 | 
				
			||||||
<option value="9">September</option>
 | 
					 | 
				
			||||||
<option value="10">October</option>
 | 
					 | 
				
			||||||
<option value="11">November</option>
 | 
					 | 
				
			||||||
<option value="12">December</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<select name="mydate_day" id="id_mydate_day">
 | 
					 | 
				
			||||||
<option value="0">empty_day</option>
 | 
					 | 
				
			||||||
<option value="1">1</option>
 | 
					 | 
				
			||||||
<option value="2">2</option>
 | 
					 | 
				
			||||||
<option value="3">3</option>
 | 
					 | 
				
			||||||
<option value="4">4</option>
 | 
					 | 
				
			||||||
<option value="5">5</option>
 | 
					 | 
				
			||||||
<option value="6">6</option>
 | 
					 | 
				
			||||||
<option value="7">7</option>
 | 
					 | 
				
			||||||
<option value="8">8</option>
 | 
					 | 
				
			||||||
<option value="9">9</option>
 | 
					 | 
				
			||||||
<option value="10">10</option>
 | 
					 | 
				
			||||||
<option value="11">11</option>
 | 
					 | 
				
			||||||
<option value="12">12</option>
 | 
					 | 
				
			||||||
<option value="13">13</option>
 | 
					 | 
				
			||||||
<option value="14">14</option>
 | 
					 | 
				
			||||||
<option value="15">15</option>
 | 
					 | 
				
			||||||
<option value="16">16</option>
 | 
					 | 
				
			||||||
<option value="17">17</option>
 | 
					 | 
				
			||||||
<option value="18">18</option>
 | 
					 | 
				
			||||||
<option value="19">19</option>
 | 
					 | 
				
			||||||
<option value="20">20</option>
 | 
					 | 
				
			||||||
<option value="21">21</option>
 | 
					 | 
				
			||||||
<option value="22">22</option>
 | 
					 | 
				
			||||||
<option value="23">23</option>
 | 
					 | 
				
			||||||
<option value="24">24</option>
 | 
					 | 
				
			||||||
<option value="25">25</option>
 | 
					 | 
				
			||||||
<option value="26">26</option>
 | 
					 | 
				
			||||||
<option value="27">27</option>
 | 
					 | 
				
			||||||
<option value="28">28</option>
 | 
					 | 
				
			||||||
<option value="29">29</option>
 | 
					 | 
				
			||||||
<option value="30">30</option>
 | 
					 | 
				
			||||||
<option value="31">31</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<select name="mydate_year" id="id_mydate_year">
 | 
					 | 
				
			||||||
<option value="0">empty_year</option>
 | 
					 | 
				
			||||||
<option value="2014">2014</option>
 | 
					 | 
				
			||||||
</select>""")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertRaisesMessage(ValueError, 'empty_label list/tuple must have 3 elements.',
 | 
					 | 
				
			||||||
            SelectDateWidget, years=('2014',), empty_label=('not enough', 'values'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_multiwidget(self):
 | 
					 | 
				
			||||||
        # MultiWidget and MultiValueField #############################################
 | 
					 | 
				
			||||||
        # MultiWidgets are widgets composed of other widgets. They are usually
 | 
					 | 
				
			||||||
        # combined with MultiValueFields - a field that is composed of other fields.
 | 
					 | 
				
			||||||
        # MulitWidgets can themselves be composed of other MultiWidgets.
 | 
					 | 
				
			||||||
        # SplitDateTimeWidget is one example of a MultiWidget.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class ComplexMultiWidget(MultiWidget):
 | 
					 | 
				
			||||||
            def __init__(self, attrs=None):
 | 
					 | 
				
			||||||
                widgets = (
 | 
					 | 
				
			||||||
                    TextInput(),
 | 
					 | 
				
			||||||
                    SelectMultiple(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
 | 
					 | 
				
			||||||
                    SplitDateTimeWidget(),
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                super(ComplexMultiWidget, self).__init__(widgets, attrs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            def decompress(self, value):
 | 
					 | 
				
			||||||
                if value:
 | 
					 | 
				
			||||||
                    data = value.split(',')
 | 
					 | 
				
			||||||
                    return [data[0], list(data[1]), datetime.datetime.strptime(data[2], "%Y-%m-%d %H:%M:%S")]
 | 
					 | 
				
			||||||
                return [None, None, None]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            def format_output(self, rendered_widgets):
 | 
					 | 
				
			||||||
                return '\n'.join(rendered_widgets)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        w = ComplexMultiWidget()
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(w.render('name', 'some text,JP,2007-04-25 06:24:00'), """<input type="text" name="name_0" value="some text" />
 | 
					 | 
				
			||||||
<select multiple="multiple" name="name_1">
 | 
					 | 
				
			||||||
<option value="J" selected="selected">John</option>
 | 
					 | 
				
			||||||
<option value="P" selected="selected">Paul</option>
 | 
					 | 
				
			||||||
<option value="G">George</option>
 | 
					 | 
				
			||||||
<option value="R">Ringo</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<input type="text" name="name_2_0" value="2007-04-25" /><input type="text" name="name_2_1" value="06:24:00" />""")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class ComplexField(MultiValueField):
 | 
					 | 
				
			||||||
            def __init__(self, required=True, widget=None, label=None, initial=None):
 | 
					 | 
				
			||||||
                fields = (
 | 
					 | 
				
			||||||
                    CharField(),
 | 
					 | 
				
			||||||
                    MultipleChoiceField(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
 | 
					 | 
				
			||||||
                    SplitDateTimeField()
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                super(ComplexField, self).__init__(fields, required, widget, label, initial)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            def compress(self, data_list):
 | 
					 | 
				
			||||||
                if data_list:
 | 
					 | 
				
			||||||
                    return '%s,%s,%s' % (data_list[0], ''.join(data_list[1]), data_list[2])
 | 
					 | 
				
			||||||
                return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        f = ComplexField(widget=w)
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]), 'some text,JP,2007-04-25 06:24:00')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Select a valid choice. X is not one of the available choices.'], f.clean, ['some text', ['X'], ['2007-04-25', '6:24:00']])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # If insufficient data is provided, None is substituted
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This field is required.'], f.clean, ['some text', ['JP']])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # test with no initial data
 | 
					 | 
				
			||||||
        self.assertTrue(f.has_changed(None, ['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # test when the data is the same as initial
 | 
					 | 
				
			||||||
        self.assertFalse(f.has_changed('some text,JP,2007-04-25 06:24:00',
 | 
					 | 
				
			||||||
            ['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # test when the first widget's data has changed
 | 
					 | 
				
			||||||
        self.assertTrue(f.has_changed('some text,JP,2007-04-25 06:24:00',
 | 
					 | 
				
			||||||
            ['other text', ['J', 'P'], ['2007-04-25', '6:24:00']]))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # test when the last widget's data has changed. this ensures that it is not
 | 
					 | 
				
			||||||
        # short circuiting while testing the widgets.
 | 
					 | 
				
			||||||
        self.assertTrue(f.has_changed('some text,JP,2007-04-25 06:24:00',
 | 
					 | 
				
			||||||
            ['some text', ['J', 'P'], ['2009-04-25', '11:44:00']]))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class ComplexFieldForm(Form):
 | 
					 | 
				
			||||||
            field1 = ComplexField(widget=w)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        f = ComplexFieldForm()
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(f.as_table(), """<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" id="id_field1_0" />
 | 
					 | 
				
			||||||
<select multiple="multiple" name="field1_1" id="id_field1_1">
 | 
					 | 
				
			||||||
<option value="J">John</option>
 | 
					 | 
				
			||||||
<option value="P">Paul</option>
 | 
					 | 
				
			||||||
<option value="G">George</option>
 | 
					 | 
				
			||||||
<option value="R">Ringo</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<input type="text" name="field1_2_0" id="id_field1_2_0" /><input type="text" name="field1_2_1" id="id_field1_2_1" /></td></tr>""")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        f = ComplexFieldForm({'field1_0': 'some text', 'field1_1': ['J', 'P'], 'field1_2_0': '2007-04-25', 'field1_2_1': '06:24:00'})
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(f.as_table(), """<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" value="some text" id="id_field1_0" />
 | 
					 | 
				
			||||||
<select multiple="multiple" name="field1_1" id="id_field1_1">
 | 
					 | 
				
			||||||
<option value="J" selected="selected">John</option>
 | 
					 | 
				
			||||||
<option value="P" selected="selected">Paul</option>
 | 
					 | 
				
			||||||
<option value="G">George</option>
 | 
					 | 
				
			||||||
<option value="R">Ringo</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr>""")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(f.cleaned_data['field1'], 'some text,JP,2007-04-25 06:24:00')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_generic_ipaddress_invalid_arguments(self):
 | 
					 | 
				
			||||||
        self.assertRaises(ValueError, GenericIPAddressField, protocol="hamster")
 | 
					 | 
				
			||||||
        self.assertRaises(ValueError, GenericIPAddressField, protocol="ipv4", unpack_ipv4=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_generic_ipaddress_as_generic(self):
 | 
					 | 
				
			||||||
        # The edge cases of the IPv6 validation code are not deeply tested
 | 
					 | 
				
			||||||
        # here, they are covered in the tests for django.utils.ipv6
 | 
					 | 
				
			||||||
        f = GenericIPAddressField()
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This field is required.'], f.clean, '')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This field is required.'], f.clean, None)
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' 127.0.0.1 '), '127.0.0.1')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '127.0.0.')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1.2.3.4.5')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '256.125.1.5')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '12345:2:3:4')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3::4')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1:2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_generic_ipaddress_as_ipv4_only(self):
 | 
					 | 
				
			||||||
        f = GenericIPAddressField(protocol="IPv4")
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This field is required.'], f.clean, '')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This field is required.'], f.clean, None)
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' 127.0.0.1 '), '127.0.0.1')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, 'foo')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '127.0.0.')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '1.2.3.4.5')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '256.125.1.5')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, 'fe80::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 address.'], f.clean, '2a02::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_generic_ipaddress_as_ipv6_only(self):
 | 
					 | 
				
			||||||
        f = GenericIPAddressField(protocol="IPv6")
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This field is required.'], f.clean, '')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This field is required.'], f.clean, None)
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '127.0.0.1')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, 'foo')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '127.0.0.')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '1.2.3.4.5')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '256.125.1.5')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '12345:2:3:4')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3::4')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1:2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_generic_ipaddress_as_generic_not_required(self):
 | 
					 | 
				
			||||||
        f = GenericIPAddressField(required=False)
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(''), '')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(None), '')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean('127.0.0.1'), '127.0.0.1')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '127.0.0.')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1.2.3.4.5')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '256.125.1.5')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '12345:2:3:4')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3::4')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
 | 
					 | 
				
			||||||
        self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1:2')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_generic_ipaddress_normalization(self):
 | 
					 | 
				
			||||||
        # Test the normalizing code
 | 
					 | 
				
			||||||
        f = GenericIPAddressField()
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' ::ffff:0a0a:0a0a  '), '::ffff:10.10.10.10')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' ::ffff:10.10.10.10  '), '::ffff:10.10.10.10')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' 2001:000:a:0000:0:fe:fe:beef  '), '2001:0:a::fe:fe:beef')
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' 2001::a:0000:0:fe:fe:beef  '), '2001:0:a::fe:fe:beef')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        f = GenericIPAddressField(unpack_ipv4=True)
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean(' ::ffff:0a0a:0a0a'), '10.10.10.10')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_slugfield_normalization(self):
 | 
					 | 
				
			||||||
        f = SlugField()
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean('    aa-bb-cc    '), 'aa-bb-cc')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_urlfield_normalization(self):
 | 
					 | 
				
			||||||
        f = URLField()
 | 
					 | 
				
			||||||
        self.assertEqual(f.clean('http://example.com/     '), 'http://example.com/')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_smart_text(self):
 | 
					 | 
				
			||||||
        class Test:
 | 
					 | 
				
			||||||
            if six.PY3:
 | 
					 | 
				
			||||||
                def __str__(self):
 | 
					 | 
				
			||||||
                    return 'ŠĐĆŽćžšđ'
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                def __str__(self):
 | 
					 | 
				
			||||||
                    return 'ŠĐĆŽćžšđ'.encode('utf-8')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class TestU:
 | 
					 | 
				
			||||||
            if six.PY3:
 | 
					 | 
				
			||||||
                def __str__(self):
 | 
					 | 
				
			||||||
                    return 'ŠĐĆŽćžšđ'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                def __bytes__(self):
 | 
					 | 
				
			||||||
                    return b'Foo'
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                def __str__(self):
 | 
					 | 
				
			||||||
                    return b'Foo'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                def __unicode__(self):
 | 
					 | 
				
			||||||
                    return '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertEqual(smart_text(Test()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
 | 
					 | 
				
			||||||
        self.assertEqual(smart_text(TestU()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
 | 
					 | 
				
			||||||
        self.assertEqual(smart_text(1), '1')
 | 
					 | 
				
			||||||
        self.assertEqual(smart_text('foo'), 'foo')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_accessing_clean(self):
 | 
					 | 
				
			||||||
        class UserForm(Form):
 | 
					 | 
				
			||||||
            username = CharField(max_length=10)
 | 
					 | 
				
			||||||
            password = CharField(widget=PasswordInput)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            def clean(self):
 | 
					 | 
				
			||||||
                data = self.cleaned_data
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if not self.errors:
 | 
					 | 
				
			||||||
                    data['username'] = data['username'].lower()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                return data
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        f = UserForm({'username': 'SirRobin', 'password': 'blue'})
 | 
					 | 
				
			||||||
        self.assertTrue(f.is_valid())
 | 
					 | 
				
			||||||
        self.assertEqual(f.cleaned_data['username'], 'sirrobin')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_changing_cleaned_data_nothing_returned(self):
 | 
					 | 
				
			||||||
        class UserForm(Form):
 | 
					 | 
				
			||||||
            username = CharField(max_length=10)
 | 
					 | 
				
			||||||
            password = CharField(widget=PasswordInput)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            def clean(self):
 | 
					 | 
				
			||||||
                self.cleaned_data['username'] = self.cleaned_data['username'].lower()
 | 
					 | 
				
			||||||
                # don't return anything
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        f = UserForm({'username': 'SirRobin', 'password': 'blue'})
 | 
					 | 
				
			||||||
        self.assertTrue(f.is_valid())
 | 
					 | 
				
			||||||
        self.assertEqual(f.cleaned_data['username'], 'sirrobin')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_changing_cleaned_data_in_clean(self):
 | 
					 | 
				
			||||||
        class UserForm(Form):
 | 
					 | 
				
			||||||
            username = CharField(max_length=10)
 | 
					 | 
				
			||||||
            password = CharField(widget=PasswordInput)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            def clean(self):
 | 
					 | 
				
			||||||
                data = self.cleaned_data
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                # Return a different dict. We have not changed self.cleaned_data.
 | 
					 | 
				
			||||||
                return {
 | 
					 | 
				
			||||||
                    'username': data['username'].lower(),
 | 
					 | 
				
			||||||
                    'password': 'this_is_not_a_secret',
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        f = UserForm({'username': 'SirRobin', 'password': 'blue'})
 | 
					 | 
				
			||||||
        self.assertTrue(f.is_valid())
 | 
					 | 
				
			||||||
        self.assertEqual(f.cleaned_data['username'], 'sirrobin')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_overriding_errorlist(self):
 | 
					 | 
				
			||||||
        @python_2_unicode_compatible
 | 
					 | 
				
			||||||
        class DivErrorList(ErrorList):
 | 
					 | 
				
			||||||
            def __str__(self):
 | 
					 | 
				
			||||||
                return self.as_divs()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            def as_divs(self):
 | 
					 | 
				
			||||||
                if not self:
 | 
					 | 
				
			||||||
                    return ''
 | 
					 | 
				
			||||||
                return '<div class="errorlist">%s</div>' % ''.join('<div class="error">%s</div>' % force_text(e) for e in self)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class CommentForm(Form):
 | 
					 | 
				
			||||||
            name = CharField(max_length=50, required=False)
 | 
					 | 
				
			||||||
            email = EmailField()
 | 
					 | 
				
			||||||
            comment = CharField()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        data = dict(email='invalid')
 | 
					 | 
				
			||||||
        f = CommentForm(data, auto_id=False, error_class=DivErrorList)
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(f.as_p(), """<p>Name: <input type="text" name="name" maxlength="50" /></p>
 | 
					 | 
				
			||||||
<div class="errorlist"><div class="error">Enter a valid email address.</div></div>
 | 
					 | 
				
			||||||
<p>Email: <input type="email" name="email" value="invalid" /></p>
 | 
					 | 
				
			||||||
<div class="errorlist"><div class="error">This field is required.</div></div>
 | 
					 | 
				
			||||||
<p>Comment: <input type="text" name="comment" /></p>""")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_multipart_encoded_form(self):
 | 
					 | 
				
			||||||
        class FormWithoutFile(Form):
 | 
					 | 
				
			||||||
            username = CharField()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class FormWithFile(Form):
 | 
					 | 
				
			||||||
            username = CharField()
 | 
					 | 
				
			||||||
            file = FileField()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class FormWithImage(Form):
 | 
					 | 
				
			||||||
            image = ImageField()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertFalse(FormWithoutFile().is_multipart())
 | 
					 | 
				
			||||||
        self.assertTrue(FormWithFile().is_multipart())
 | 
					 | 
				
			||||||
        self.assertTrue(FormWithImage().is_multipart())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_selectdatewidget_required(self):
 | 
					 | 
				
			||||||
        class GetNotRequiredDate(Form):
 | 
					 | 
				
			||||||
            mydate = DateField(widget=SelectDateWidget, required=False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class GetRequiredDate(Form):
 | 
					 | 
				
			||||||
            mydate = DateField(widget=SelectDateWidget, required=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertFalse(GetNotRequiredDate().fields['mydate'].widget.is_required)
 | 
					 | 
				
			||||||
        self.assertTrue(GetRequiredDate().fields['mydate'].widget.is_required)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@override_settings(USE_L10N=True)
 | 
					 | 
				
			||||||
class FormsExtraL10NTestCase(TestCase):
 | 
					 | 
				
			||||||
    def setUp(self):
 | 
					 | 
				
			||||||
        super(FormsExtraL10NTestCase, self).setUp()
 | 
					 | 
				
			||||||
        translation.activate('nl')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def tearDown(self):
 | 
					 | 
				
			||||||
        translation.deactivate()
 | 
					 | 
				
			||||||
        super(FormsExtraL10NTestCase, self).tearDown()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_l10n(self):
 | 
					 | 
				
			||||||
        w = SelectDateWidget(years=('2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016'))
 | 
					 | 
				
			||||||
        self.assertEqual(w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date'), '13-08-2010')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.assertHTMLEqual(w.render('date', '13-08-2010'), """<select name="date_day" id="id_date_day">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="1">1</option>
 | 
					 | 
				
			||||||
<option value="2">2</option>
 | 
					 | 
				
			||||||
<option value="3">3</option>
 | 
					 | 
				
			||||||
<option value="4">4</option>
 | 
					 | 
				
			||||||
<option value="5">5</option>
 | 
					 | 
				
			||||||
<option value="6">6</option>
 | 
					 | 
				
			||||||
<option value="7">7</option>
 | 
					 | 
				
			||||||
<option value="8">8</option>
 | 
					 | 
				
			||||||
<option value="9">9</option>
 | 
					 | 
				
			||||||
<option value="10">10</option>
 | 
					 | 
				
			||||||
<option value="11">11</option>
 | 
					 | 
				
			||||||
<option value="12">12</option>
 | 
					 | 
				
			||||||
<option value="13" selected="selected">13</option>
 | 
					 | 
				
			||||||
<option value="14">14</option>
 | 
					 | 
				
			||||||
<option value="15">15</option>
 | 
					 | 
				
			||||||
<option value="16">16</option>
 | 
					 | 
				
			||||||
<option value="17">17</option>
 | 
					 | 
				
			||||||
<option value="18">18</option>
 | 
					 | 
				
			||||||
<option value="19">19</option>
 | 
					 | 
				
			||||||
<option value="20">20</option>
 | 
					 | 
				
			||||||
<option value="21">21</option>
 | 
					 | 
				
			||||||
<option value="22">22</option>
 | 
					 | 
				
			||||||
<option value="23">23</option>
 | 
					 | 
				
			||||||
<option value="24">24</option>
 | 
					 | 
				
			||||||
<option value="25">25</option>
 | 
					 | 
				
			||||||
<option value="26">26</option>
 | 
					 | 
				
			||||||
<option value="27">27</option>
 | 
					 | 
				
			||||||
<option value="28">28</option>
 | 
					 | 
				
			||||||
<option value="29">29</option>
 | 
					 | 
				
			||||||
<option value="30">30</option>
 | 
					 | 
				
			||||||
<option value="31">31</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<select name="date_month" id="id_date_month">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="1">januari</option>
 | 
					 | 
				
			||||||
<option value="2">februari</option>
 | 
					 | 
				
			||||||
<option value="3">maart</option>
 | 
					 | 
				
			||||||
<option value="4">april</option>
 | 
					 | 
				
			||||||
<option value="5">mei</option>
 | 
					 | 
				
			||||||
<option value="6">juni</option>
 | 
					 | 
				
			||||||
<option value="7">juli</option>
 | 
					 | 
				
			||||||
<option value="8" selected="selected">augustus</option>
 | 
					 | 
				
			||||||
<option value="9">september</option>
 | 
					 | 
				
			||||||
<option value="10">oktober</option>
 | 
					 | 
				
			||||||
<option value="11">november</option>
 | 
					 | 
				
			||||||
<option value="12">december</option>
 | 
					 | 
				
			||||||
</select>
 | 
					 | 
				
			||||||
<select name="date_year" id="id_date_year">
 | 
					 | 
				
			||||||
<option value="0">---</option>
 | 
					 | 
				
			||||||
<option value="2007">2007</option>
 | 
					 | 
				
			||||||
<option value="2008">2008</option>
 | 
					 | 
				
			||||||
<option value="2009">2009</option>
 | 
					 | 
				
			||||||
<option value="2010" selected="selected">2010</option>
 | 
					 | 
				
			||||||
<option value="2011">2011</option>
 | 
					 | 
				
			||||||
<option value="2012">2012</option>
 | 
					 | 
				
			||||||
<option value="2013">2013</option>
 | 
					 | 
				
			||||||
<option value="2014">2014</option>
 | 
					 | 
				
			||||||
<option value="2015">2015</option>
 | 
					 | 
				
			||||||
<option value="2016">2016</option>
 | 
					 | 
				
			||||||
</select>""")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Years before 1900 work
 | 
					 | 
				
			||||||
        w = SelectDateWidget(years=('1899',))
 | 
					 | 
				
			||||||
        self.assertEqual(w.value_from_datadict({'date_year': '1899', 'date_month': '8', 'date_day': '13'}, {}, 'date'), '13-08-1899')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_l10n_date_changed(self):
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        Ensure that DateField.has_changed() with SelectDateWidget works
 | 
					 | 
				
			||||||
        correctly with a localized date format.
 | 
					 | 
				
			||||||
        Refs #17165.
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        # With Field.show_hidden_initial=False -----------------------
 | 
					 | 
				
			||||||
        b = GetDate({
 | 
					 | 
				
			||||||
            'mydate_year': '2008',
 | 
					 | 
				
			||||||
            'mydate_month': '4',
 | 
					 | 
				
			||||||
            'mydate_day': '1',
 | 
					 | 
				
			||||||
        }, initial={'mydate': datetime.date(2008, 4, 1)})
 | 
					 | 
				
			||||||
        self.assertFalse(b.has_changed())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        b = GetDate({
 | 
					 | 
				
			||||||
            'mydate_year': '2008',
 | 
					 | 
				
			||||||
            'mydate_month': '4',
 | 
					 | 
				
			||||||
            'mydate_day': '2',
 | 
					 | 
				
			||||||
        }, initial={'mydate': datetime.date(2008, 4, 1)})
 | 
					 | 
				
			||||||
        self.assertTrue(b.has_changed())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # With Field.show_hidden_initial=True ------------------------
 | 
					 | 
				
			||||||
        b = GetDateShowHiddenInitial({
 | 
					 | 
				
			||||||
            'mydate_year': '2008',
 | 
					 | 
				
			||||||
            'mydate_month': '4',
 | 
					 | 
				
			||||||
            'mydate_day': '1',
 | 
					 | 
				
			||||||
            'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 1))
 | 
					 | 
				
			||||||
        }, initial={'mydate': datetime.date(2008, 4, 1)})
 | 
					 | 
				
			||||||
        self.assertFalse(b.has_changed())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        b = GetDateShowHiddenInitial({
 | 
					 | 
				
			||||||
            'mydate_year': '2008',
 | 
					 | 
				
			||||||
            'mydate_month': '4',
 | 
					 | 
				
			||||||
            'mydate_day': '22',
 | 
					 | 
				
			||||||
            'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 1))
 | 
					 | 
				
			||||||
        }, initial={'mydate': datetime.date(2008, 4, 1)})
 | 
					 | 
				
			||||||
        self.assertTrue(b.has_changed())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        b = GetDateShowHiddenInitial({
 | 
					 | 
				
			||||||
            'mydate_year': '2008',
 | 
					 | 
				
			||||||
            'mydate_month': '4',
 | 
					 | 
				
			||||||
            'mydate_day': '22',
 | 
					 | 
				
			||||||
            'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 1))
 | 
					 | 
				
			||||||
        }, initial={'mydate': datetime.date(2008, 4, 22)})
 | 
					 | 
				
			||||||
        self.assertTrue(b.has_changed())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        b = GetDateShowHiddenInitial({
 | 
					 | 
				
			||||||
            'mydate_year': '2008',
 | 
					 | 
				
			||||||
            'mydate_month': '4',
 | 
					 | 
				
			||||||
            'mydate_day': '22',
 | 
					 | 
				
			||||||
            'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 22))
 | 
					 | 
				
			||||||
        }, initial={'mydate': datetime.date(2008, 4, 1)})
 | 
					 | 
				
			||||||
        self.assertFalse(b.has_changed())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_l10n_invalid_date_in(self):
 | 
					 | 
				
			||||||
        # Invalid dates shouldn't be allowed
 | 
					 | 
				
			||||||
        a = GetDate({'mydate_month': '2', 'mydate_day': '31', 'mydate_year': '2010'})
 | 
					 | 
				
			||||||
        self.assertFalse(a.is_valid())
 | 
					 | 
				
			||||||
        # 'Geef een geldige datum op.' = 'Enter a valid date.'
 | 
					 | 
				
			||||||
        self.assertEqual(a.errors, {'mydate': ['Geef een geldige datum op.']})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_form_label_association(self):
 | 
					 | 
				
			||||||
        # label tag is correctly associated with first rendered dropdown
 | 
					 | 
				
			||||||
        a = GetDate({'mydate_month': '1', 'mydate_day': '1', 'mydate_year': '2010'})
 | 
					 | 
				
			||||||
        self.assertIn('<label for="id_mydate_day">', a.as_p())
 | 
					 | 
				
			||||||
| 
						 | 
					@ -43,11 +43,11 @@ from django.core.files.uploadedfile import SimpleUploadedFile
 | 
				
			||||||
from django.forms import (
 | 
					from django.forms import (
 | 
				
			||||||
    BooleanField, CharField, ChoiceField, ComboField, DateField, DateTimeField,
 | 
					    BooleanField, CharField, ChoiceField, ComboField, DateField, DateTimeField,
 | 
				
			||||||
    DecimalField, DurationField, EmailField, Field, FileField, FilePathField,
 | 
					    DecimalField, DurationField, EmailField, Field, FileField, FilePathField,
 | 
				
			||||||
    FloatField, Form, forms, HiddenInput, ImageField, IntegerField,
 | 
					    FloatField, Form, forms, GenericIPAddressField, HiddenInput, ImageField,
 | 
				
			||||||
    MultipleChoiceField, NullBooleanField, NumberInput, PasswordInput,
 | 
					    IntegerField, MultipleChoiceField, NullBooleanField, NumberInput,
 | 
				
			||||||
    RadioSelect, RegexField, SplitDateTimeField, TextInput, Textarea,
 | 
					    PasswordInput, RadioSelect, RegexField, SlugField, SplitDateTimeField,
 | 
				
			||||||
    TimeField, TypedChoiceField, TypedMultipleChoiceField, URLField, UUIDField,
 | 
					    TextInput, Textarea, TimeField, TypedChoiceField, TypedMultipleChoiceField,
 | 
				
			||||||
    ValidationError, Widget,
 | 
					    URLField, UUIDField, ValidationError, Widget,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from django.test import SimpleTestCase, ignore_warnings
 | 
					from django.test import SimpleTestCase, ignore_warnings
 | 
				
			||||||
from django.utils import formats
 | 
					from django.utils import formats
 | 
				
			||||||
| 
						 | 
					@ -906,6 +906,10 @@ class FieldsTests(SimpleTestCase):
 | 
				
			||||||
        f = URLField(required=False)
 | 
					        f = URLField(required=False)
 | 
				
			||||||
        self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'", f.clean, 23)
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid URL.'", f.clean, 23)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_urlfield_normalization(self):
 | 
				
			||||||
 | 
					        f = URLField()
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean('http://example.com/     '), 'http://example.com/')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # BooleanField ################################################################
 | 
					    # BooleanField ################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_booleanfield_1(self):
 | 
					    def test_booleanfield_1(self):
 | 
				
			||||||
| 
						 | 
					@ -1385,6 +1389,96 @@ class FieldsTests(SimpleTestCase):
 | 
				
			||||||
        self.assertFalse(f.has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), ['06/05/2008', '12:40']))
 | 
					        self.assertFalse(f.has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), ['06/05/2008', '12:40']))
 | 
				
			||||||
        self.assertTrue(f.has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), ['06/05/2008', '12:41']))
 | 
					        self.assertTrue(f.has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), ['06/05/2008', '12:41']))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # GenericIPAddressField #######################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_generic_ipaddress_invalid_arguments(self):
 | 
				
			||||||
 | 
					        self.assertRaises(ValueError, GenericIPAddressField, protocol="hamster")
 | 
				
			||||||
 | 
					        self.assertRaises(ValueError, GenericIPAddressField, protocol="ipv4", unpack_ipv4=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_generic_ipaddress_as_generic(self):
 | 
				
			||||||
 | 
					        # The edge cases of the IPv6 validation code are not deeply tested
 | 
				
			||||||
 | 
					        # here, they are covered in the tests for django.utils.ipv6
 | 
				
			||||||
 | 
					        f = GenericIPAddressField()
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, '')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, None)
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' 127.0.0.1 '), '127.0.0.1')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'", f.clean, 'foo')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'", f.clean, '127.0.0.')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'", f.clean, '1.2.3.4.5')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'", f.clean, '256.125.1.5')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '12345:2:3:4')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '1::2:3::4')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, 'foo::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '1::2:3:4:5:6:7:8')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '1:2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_generic_ipaddress_as_ipv4_only(self):
 | 
				
			||||||
 | 
					        f = GenericIPAddressField(protocol="IPv4")
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, '')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, None)
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' 127.0.0.1 '), '127.0.0.1')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'", f.clean, 'foo')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'", f.clean, '127.0.0.')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'", f.clean, '1.2.3.4.5')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'", f.clean, '256.125.1.5')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'", f.clean, 'fe80::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'", f.clean, '2a02::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_generic_ipaddress_as_ipv6_only(self):
 | 
				
			||||||
 | 
					        f = GenericIPAddressField(protocol="IPv6")
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, '')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, None)
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv6 address.'", f.clean, '127.0.0.1')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv6 address.'", f.clean, 'foo')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv6 address.'", f.clean, '127.0.0.')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv6 address.'", f.clean, '1.2.3.4.5')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv6 address.'", f.clean, '256.125.1.5')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '12345:2:3:4')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '1::2:3::4')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, 'foo::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '1::2:3:4:5:6:7:8')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '1:2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_generic_ipaddress_as_generic_not_required(self):
 | 
				
			||||||
 | 
					        f = GenericIPAddressField(required=False)
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(''), '')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(None), '')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean('127.0.0.1'), '127.0.0.1')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'", f.clean, 'foo')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'", f.clean, '127.0.0.')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'", f.clean, '1.2.3.4.5')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'", f.clean, '256.125.1.5')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '12345:2:3:4')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '1::2:3::4')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, 'foo::223:6cff:fe8a:2e8a')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '1::2:3:4:5:6:7:8')
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'", f.clean, '1:2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_generic_ipaddress_normalization(self):
 | 
				
			||||||
 | 
					        # Test the normalizing code
 | 
				
			||||||
 | 
					        f = GenericIPAddressField()
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' ::ffff:0a0a:0a0a  '), '::ffff:10.10.10.10')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' ::ffff:10.10.10.10  '), '::ffff:10.10.10.10')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' 2001:000:a:0000:0:fe:fe:beef  '), '2001:0:a::fe:fe:beef')
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' 2001::a:0000:0:fe:fe:beef  '), '2001:0:a::fe:fe:beef')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        f = GenericIPAddressField(unpack_ipv4=True)
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean(' ::ffff:0a0a:0a0a'), '10.10.10.10')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # SlugField ###################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_slugfield_normalization(self):
 | 
				
			||||||
 | 
					        f = SlugField()
 | 
				
			||||||
 | 
					        self.assertEqual(f.clean('    aa-bb-cc    '), 'aa-bb-cc')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # UUIDField ###################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_uuidfield_1(self):
 | 
					    def test_uuidfield_1(self):
 | 
				
			||||||
        field = UUIDField()
 | 
					        field = UUIDField()
 | 
				
			||||||
        value = field.clean('550e8400e29b41d4a716446655440000')
 | 
					        value = field.clean('550e8400e29b41d4a716446655440000')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,9 +11,10 @@ from django.core.validators import RegexValidator
 | 
				
			||||||
from django.forms import (
 | 
					from django.forms import (
 | 
				
			||||||
    BooleanField, CharField, CheckboxSelectMultiple, ChoiceField, DateField,
 | 
					    BooleanField, CharField, CheckboxSelectMultiple, ChoiceField, DateField,
 | 
				
			||||||
    DateTimeField, EmailField, FileField, FloatField, Form, forms, HiddenInput,
 | 
					    DateTimeField, EmailField, FileField, FloatField, Form, forms, HiddenInput,
 | 
				
			||||||
    IntegerField, MultipleChoiceField, MultipleHiddenInput, MultiValueField,
 | 
					    ImageField, IntegerField, MultipleChoiceField, MultipleHiddenInput,
 | 
				
			||||||
    NullBooleanField, PasswordInput, RadioSelect, Select, SplitDateTimeField,
 | 
					    MultiValueField, NullBooleanField, PasswordInput, RadioSelect, Select,
 | 
				
			||||||
    Textarea, TextInput, TimeField, ValidationError, widgets
 | 
					    SplitDateTimeField, SplitHiddenDateTimeWidget, Textarea, TextInput,
 | 
				
			||||||
 | 
					    TimeField, ValidationError,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from django.forms.utils import ErrorList
 | 
					from django.forms.utils import ErrorList
 | 
				
			||||||
from django.http import QueryDict
 | 
					from django.http import QueryDict
 | 
				
			||||||
| 
						 | 
					@ -21,7 +22,7 @@ from django.template import Template, Context
 | 
				
			||||||
from django.test import TestCase
 | 
					from django.test import TestCase
 | 
				
			||||||
from django.test.utils import str_prefix
 | 
					from django.test.utils import str_prefix
 | 
				
			||||||
from django.utils.datastructures import MultiValueDict
 | 
					from django.utils.datastructures import MultiValueDict
 | 
				
			||||||
from django.utils.encoding import force_text
 | 
					from django.utils.encoding import force_text, python_2_unicode_compatible
 | 
				
			||||||
from django.utils.html import format_html
 | 
					from django.utils.html import format_html
 | 
				
			||||||
from django.utils.safestring import mark_safe, SafeData
 | 
					from django.utils.safestring import mark_safe, SafeData
 | 
				
			||||||
from django.utils import six
 | 
					from django.utils import six
 | 
				
			||||||
| 
						 | 
					@ -1945,7 +1946,7 @@ class FormsTestCase(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_label_split_datetime_not_displayed(self):
 | 
					    def test_label_split_datetime_not_displayed(self):
 | 
				
			||||||
        class EventForm(Form):
 | 
					        class EventForm(Form):
 | 
				
			||||||
            happened_at = SplitDateTimeField(widget=widgets.SplitHiddenDateTimeWidget)
 | 
					            happened_at = SplitDateTimeField(widget=SplitHiddenDateTimeWidget)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        form = EventForm()
 | 
					        form = EventForm()
 | 
				
			||||||
        self.assertHTMLEqual(form.as_ul(), '<input type="hidden" name="happened_at_0" id="id_happened_at_0" /><input type="hidden" name="happened_at_1" id="id_happened_at_1" />')
 | 
					        self.assertHTMLEqual(form.as_ul(), '<input type="hidden" name="happened_at_0" id="id_happened_at_0" /><input type="hidden" name="happened_at_1" id="id_happened_at_1" />')
 | 
				
			||||||
| 
						 | 
					@ -2399,6 +2400,31 @@ class FormsTestCase(TestCase):
 | 
				
			||||||
<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>"""
 | 
					<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>"""
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_errorlist_override(self):
 | 
				
			||||||
 | 
					        @python_2_unicode_compatible
 | 
				
			||||||
 | 
					        class DivErrorList(ErrorList):
 | 
				
			||||||
 | 
					            def __str__(self):
 | 
				
			||||||
 | 
					                return self.as_divs()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def as_divs(self):
 | 
				
			||||||
 | 
					                if not self:
 | 
				
			||||||
 | 
					                    return ''
 | 
				
			||||||
 | 
					                return '<div class="errorlist">%s</div>' % ''.join(
 | 
				
			||||||
 | 
					                    '<div class="error">%s</div>' % force_text(e) for e in self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class CommentForm(Form):
 | 
				
			||||||
 | 
					            name = CharField(max_length=50, required=False)
 | 
				
			||||||
 | 
					            email = EmailField()
 | 
				
			||||||
 | 
					            comment = CharField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        data = dict(email='invalid')
 | 
				
			||||||
 | 
					        f = CommentForm(data, auto_id=False, error_class=DivErrorList)
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(f.as_p(), """<p>Name: <input type="text" name="name" maxlength="50" /></p>
 | 
				
			||||||
 | 
					<div class="errorlist"><div class="error">Enter a valid email address.</div></div>
 | 
				
			||||||
 | 
					<p>Email: <input type="email" name="email" value="invalid" /></p>
 | 
				
			||||||
 | 
					<div class="errorlist"><div class="error">This field is required.</div></div>
 | 
				
			||||||
 | 
					<p>Comment: <input type="text" name="comment" /></p>""")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_baseform_repr(self):
 | 
					    def test_baseform_repr(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        BaseForm.__repr__() should contain some basic information about the
 | 
					        BaseForm.__repr__() should contain some basic information about the
 | 
				
			||||||
| 
						 | 
					@ -2423,3 +2449,66 @@ class FormsTestCase(TestCase):
 | 
				
			||||||
        self.assertRaises(AttributeError, lambda: p.cleaned_data)
 | 
					        self.assertRaises(AttributeError, lambda: p.cleaned_data)
 | 
				
			||||||
        self.assertFalse(p.is_valid())
 | 
					        self.assertFalse(p.is_valid())
 | 
				
			||||||
        self.assertEqual(p.cleaned_data, {'first_name': 'John', 'last_name': 'Lennon'})
 | 
					        self.assertEqual(p.cleaned_data, {'first_name': 'John', 'last_name': 'Lennon'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_accessing_clean(self):
 | 
				
			||||||
 | 
					        class UserForm(Form):
 | 
				
			||||||
 | 
					            username = CharField(max_length=10)
 | 
				
			||||||
 | 
					            password = CharField(widget=PasswordInput)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def clean(self):
 | 
				
			||||||
 | 
					                data = self.cleaned_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if not self.errors:
 | 
				
			||||||
 | 
					                    data['username'] = data['username'].lower()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        f = UserForm({'username': 'SirRobin', 'password': 'blue'})
 | 
				
			||||||
 | 
					        self.assertTrue(f.is_valid())
 | 
				
			||||||
 | 
					        self.assertEqual(f.cleaned_data['username'], 'sirrobin')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_changing_cleaned_data_nothing_returned(self):
 | 
				
			||||||
 | 
					        class UserForm(Form):
 | 
				
			||||||
 | 
					            username = CharField(max_length=10)
 | 
				
			||||||
 | 
					            password = CharField(widget=PasswordInput)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def clean(self):
 | 
				
			||||||
 | 
					                self.cleaned_data['username'] = self.cleaned_data['username'].lower()
 | 
				
			||||||
 | 
					                # don't return anything
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        f = UserForm({'username': 'SirRobin', 'password': 'blue'})
 | 
				
			||||||
 | 
					        self.assertTrue(f.is_valid())
 | 
				
			||||||
 | 
					        self.assertEqual(f.cleaned_data['username'], 'sirrobin')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_changing_cleaned_data_in_clean(self):
 | 
				
			||||||
 | 
					        class UserForm(Form):
 | 
				
			||||||
 | 
					            username = CharField(max_length=10)
 | 
				
			||||||
 | 
					            password = CharField(widget=PasswordInput)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def clean(self):
 | 
				
			||||||
 | 
					                data = self.cleaned_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Return a different dict. We have not changed self.cleaned_data.
 | 
				
			||||||
 | 
					                return {
 | 
				
			||||||
 | 
					                    'username': data['username'].lower(),
 | 
				
			||||||
 | 
					                    'password': 'this_is_not_a_secret',
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        f = UserForm({'username': 'SirRobin', 'password': 'blue'})
 | 
				
			||||||
 | 
					        self.assertTrue(f.is_valid())
 | 
				
			||||||
 | 
					        self.assertEqual(f.cleaned_data['username'], 'sirrobin')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_multipart_encoded_form(self):
 | 
				
			||||||
 | 
					        class FormWithoutFile(Form):
 | 
				
			||||||
 | 
					            username = CharField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class FormWithFile(Form):
 | 
				
			||||||
 | 
					            username = CharField()
 | 
				
			||||||
 | 
					            file = FileField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class FormWithImage(Form):
 | 
				
			||||||
 | 
					            image = ImageField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertFalse(FormWithoutFile().is_multipart())
 | 
				
			||||||
 | 
					        self.assertTrue(FormWithFile().is_multipart())
 | 
				
			||||||
 | 
					        self.assertTrue(FormWithImage().is_multipart())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,23 +8,25 @@ from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase
 | 
				
			||||||
from django.core.files.uploadedfile import SimpleUploadedFile
 | 
					from django.core.files.uploadedfile import SimpleUploadedFile
 | 
				
			||||||
from django.core.urlresolvers import reverse
 | 
					from django.core.urlresolvers import reverse
 | 
				
			||||||
from django.forms import (
 | 
					from django.forms import (
 | 
				
			||||||
    BooleanField, CheckboxInput, CheckboxSelectMultiple, ChoiceField,
 | 
					    BooleanField, CharField, CheckboxInput, CheckboxSelectMultiple,
 | 
				
			||||||
    ClearableFileInput, DateInput, DateTimeInput, FileInput,
 | 
					    ChoiceField, ClearableFileInput, DateField, DateInput, DateTimeInput,
 | 
				
			||||||
    Form, HiddenInput, MultipleHiddenInput, MultiWidget, NullBooleanSelect,
 | 
					    FileInput, Form, HiddenInput, MultipleChoiceField, MultipleHiddenInput,
 | 
				
			||||||
    PasswordInput, RadioSelect, Select, SelectMultiple, SplitDateTimeWidget,
 | 
					    MultiValueField, MultiWidget, NullBooleanSelect, PasswordInput,
 | 
				
			||||||
    Textarea, TextInput, TimeInput,
 | 
					    RadioSelect, Select, SelectMultiple, SplitDateTimeField,
 | 
				
			||||||
 | 
					    SplitDateTimeWidget, Textarea, TextInput, TimeInput, ValidationError,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					from django.forms.extras import SelectDateWidget
 | 
				
			||||||
from django.forms.widgets import RadioFieldRenderer
 | 
					from django.forms.widgets import RadioFieldRenderer
 | 
				
			||||||
from django.utils.safestring import mark_safe, SafeData
 | 
					from django.utils.safestring import mark_safe, SafeData
 | 
				
			||||||
from django.utils import six
 | 
					from django.utils import six, translation
 | 
				
			||||||
from django.utils.translation import activate, deactivate, override
 | 
					 | 
				
			||||||
from django.test import TestCase, override_settings
 | 
					from django.test import TestCase, override_settings
 | 
				
			||||||
from django.utils.encoding import python_2_unicode_compatible, force_text
 | 
					from django.utils.dates import MONTHS_AP
 | 
				
			||||||
 | 
					from django.utils.encoding import force_text, python_2_unicode_compatible
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..models import Article
 | 
					from ..models import Article
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FormsWidgetTestCase(TestCase):
 | 
					class FormsWidgetTests(TestCase):
 | 
				
			||||||
    # Each Widget class corresponds to an HTML form widget. A Widget knows how to
 | 
					    # Each Widget class corresponds to an HTML form widget. A Widget knows how to
 | 
				
			||||||
    # render itself, given a field name and some data. Widgets don't perform
 | 
					    # render itself, given a field name and some data. Widgets don't perform
 | 
				
			||||||
    # validation.
 | 
					    # validation.
 | 
				
			||||||
| 
						 | 
					@ -1020,6 +1022,132 @@ beatle J R Ringo False""")
 | 
				
			||||||
        self.assertHTMLEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51, 34)), '<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" name="date_1" value="12:51:34" />')
 | 
					        self.assertHTMLEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51, 34)), '<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" name="date_1" value="12:51:34" />')
 | 
				
			||||||
        self.assertHTMLEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51)), '<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" name="date_1" value="12:51:00" />')
 | 
					        self.assertHTMLEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51)), '<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" name="date_1" value="12:51:00" />')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_multiwidget(self):
 | 
				
			||||||
 | 
					        # MultiWidgets are widgets composed of other widgets. They are usually
 | 
				
			||||||
 | 
					        # combined with MultiValueFields - a field that is composed of other fields.
 | 
				
			||||||
 | 
					        # MulitWidgets can themselves be composed of other MultiWidgets.
 | 
				
			||||||
 | 
					        # SplitDateTimeWidget is one example of a MultiWidget.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class ComplexMultiWidget(MultiWidget):
 | 
				
			||||||
 | 
					            def __init__(self, attrs=None):
 | 
				
			||||||
 | 
					                widgets = (
 | 
				
			||||||
 | 
					                    TextInput(),
 | 
				
			||||||
 | 
					                    SelectMultiple(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
 | 
				
			||||||
 | 
					                    SplitDateTimeWidget(),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                super(ComplexMultiWidget, self).__init__(widgets, attrs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def decompress(self, value):
 | 
				
			||||||
 | 
					                if value:
 | 
				
			||||||
 | 
					                    data = value.split(',')
 | 
				
			||||||
 | 
					                    return [data[0], list(data[1]), datetime.datetime.strptime(data[2], "%Y-%m-%d %H:%M:%S")]
 | 
				
			||||||
 | 
					                return [None, None, None]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def format_output(self, rendered_widgets):
 | 
				
			||||||
 | 
					                return '\n'.join(rendered_widgets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        w = ComplexMultiWidget()
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            w.render('name', 'some text,JP,2007-04-25 06:24:00'),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <input type="text" name="name_0" value="some text" />
 | 
				
			||||||
 | 
					            <select multiple="multiple" name="name_1">
 | 
				
			||||||
 | 
					                <option value="J" selected="selected">John</option>
 | 
				
			||||||
 | 
					                <option value="P" selected="selected">Paul</option>
 | 
				
			||||||
 | 
					                <option value="G">George</option>
 | 
				
			||||||
 | 
					                <option value="R">Ringo</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					            <input type="text" name="name_2_0" value="2007-04-25" />
 | 
				
			||||||
 | 
					            <input type="text" name="name_2_1" value="06:24:00" />
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class ComplexField(MultiValueField):
 | 
				
			||||||
 | 
					            def __init__(self, required=True, widget=None, label=None, initial=None):
 | 
				
			||||||
 | 
					                fields = (
 | 
				
			||||||
 | 
					                    CharField(),
 | 
				
			||||||
 | 
					                    MultipleChoiceField(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
 | 
				
			||||||
 | 
					                    SplitDateTimeField()
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                super(ComplexField, self).__init__(fields, required, widget, label, initial)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def compress(self, data_list):
 | 
				
			||||||
 | 
					                if data_list:
 | 
				
			||||||
 | 
					                    return '%s,%s,%s' % (data_list[0], ''.join(data_list[1]), data_list[2])
 | 
				
			||||||
 | 
					                return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        f = ComplexField(widget=w)
 | 
				
			||||||
 | 
					        self.assertEqual(
 | 
				
			||||||
 | 
					            f.clean(['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]),
 | 
				
			||||||
 | 
					            'some text,JP,2007-04-25 06:24:00',
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with self.assertRaisesMessage(ValidationError,
 | 
				
			||||||
 | 
					                "'Select a valid choice. X is not one of the available choices.'"):
 | 
				
			||||||
 | 
					            f.clean(['some text', ['X'], ['2007-04-25', '6:24:00']])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If insufficient data is provided, None is substituted
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, ['some text', ['JP']])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # test with no initial data
 | 
				
			||||||
 | 
					        self.assertTrue(f.has_changed(None, ['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # test when the data is the same as initial
 | 
				
			||||||
 | 
					        self.assertFalse(f.has_changed('some text,JP,2007-04-25 06:24:00',
 | 
				
			||||||
 | 
					            ['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # test when the first widget's data has changed
 | 
				
			||||||
 | 
					        self.assertTrue(f.has_changed('some text,JP,2007-04-25 06:24:00',
 | 
				
			||||||
 | 
					            ['other text', ['J', 'P'], ['2007-04-25', '6:24:00']]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # test when the last widget's data has changed. this ensures that it is not
 | 
				
			||||||
 | 
					        # short circuiting while testing the widgets.
 | 
				
			||||||
 | 
					        self.assertTrue(f.has_changed('some text,JP,2007-04-25 06:24:00',
 | 
				
			||||||
 | 
					            ['some text', ['J', 'P'], ['2009-04-25', '11:44:00']]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class ComplexFieldForm(Form):
 | 
				
			||||||
 | 
					            field1 = ComplexField(widget=w)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        f = ComplexFieldForm()
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            f.as_table(),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <tr><th><label for="id_field1_0">Field1:</label></th>
 | 
				
			||||||
 | 
					            <td><input type="text" name="field1_0" id="id_field1_0" />
 | 
				
			||||||
 | 
					            <select multiple="multiple" name="field1_1" id="id_field1_1">
 | 
				
			||||||
 | 
					            <option value="J">John</option>
 | 
				
			||||||
 | 
					            <option value="P">Paul</option>
 | 
				
			||||||
 | 
					            <option value="G">George</option>
 | 
				
			||||||
 | 
					            <option value="R">Ringo</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					            <input type="text" name="field1_2_0" id="id_field1_2_0" />
 | 
				
			||||||
 | 
					            <input type="text" name="field1_2_1" id="id_field1_2_1" /></td></tr>
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        f = ComplexFieldForm({
 | 
				
			||||||
 | 
					            'field1_0': 'some text',
 | 
				
			||||||
 | 
					            'field1_1': ['J', 'P'],
 | 
				
			||||||
 | 
					            'field1_2_0': '2007-04-25',
 | 
				
			||||||
 | 
					            'field1_2_1': '06:24:00',
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            f.as_table(),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <tr><th><label for="id_field1_0">Field1:</label></th>
 | 
				
			||||||
 | 
					            <td><input type="text" name="field1_0" value="some text" id="id_field1_0" />
 | 
				
			||||||
 | 
					            <select multiple="multiple" name="field1_1" id="id_field1_1">
 | 
				
			||||||
 | 
					            <option value="J" selected="selected">John</option>
 | 
				
			||||||
 | 
					            <option value="P" selected="selected">Paul</option>
 | 
				
			||||||
 | 
					            <option value="G">George</option>
 | 
				
			||||||
 | 
					            <option value="R">Ringo</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					            <input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" />
 | 
				
			||||||
 | 
					            <input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr>
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(f.cleaned_data['field1'], 'some text,JP,2007-04-25 06:24:00')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NullBooleanSelectLazyForm(Form):
 | 
					class NullBooleanSelectLazyForm(Form):
 | 
				
			||||||
    """Form to test for lazy evaluation. Refs #17190"""
 | 
					    """Form to test for lazy evaluation. Refs #17190"""
 | 
				
			||||||
| 
						 | 
					@ -1027,14 +1155,14 @@ class NullBooleanSelectLazyForm(Form):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@override_settings(USE_L10N=True)
 | 
					@override_settings(USE_L10N=True)
 | 
				
			||||||
class FormsI18NWidgetsTestCase(TestCase):
 | 
					class FormsI18NWidgetsTests(TestCase):
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        super(FormsI18NWidgetsTestCase, self).setUp()
 | 
					        super(FormsI18NWidgetsTests, self).setUp()
 | 
				
			||||||
        activate('de-at')
 | 
					        translation.activate('de-at')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tearDown(self):
 | 
					    def tearDown(self):
 | 
				
			||||||
        deactivate()
 | 
					        translation.deactivate()
 | 
				
			||||||
        super(FormsI18NWidgetsTestCase, self).tearDown()
 | 
					        super(FormsI18NWidgetsTests, self).tearDown()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_datetimeinput(self):
 | 
					    def test_datetimeinput(self):
 | 
				
			||||||
        w = DateTimeInput()
 | 
					        w = DateTimeInput()
 | 
				
			||||||
| 
						 | 
					@ -1056,14 +1184,20 @@ class FormsI18NWidgetsTestCase(TestCase):
 | 
				
			||||||
        d = datetime.datetime(2007, 9, 17, 12, 51, 34, 482548)
 | 
					        d = datetime.datetime(2007, 9, 17, 12, 51, 34, 482548)
 | 
				
			||||||
        with self.settings(USE_L10N=False):
 | 
					        with self.settings(USE_L10N=False):
 | 
				
			||||||
            self.assertHTMLEqual(w.render('date', d), '<input type="text" name="date" value="2007-09-17 12:51:34" />')
 | 
					            self.assertHTMLEqual(w.render('date', d), '<input type="text" name="date" value="2007-09-17 12:51:34" />')
 | 
				
			||||||
        with override('es'):
 | 
					        with translation.override('es'):
 | 
				
			||||||
            self.assertHTMLEqual(w.render('date', d), '<input type="text" name="date" value="17/09/2007 12:51:34" />')
 | 
					            self.assertHTMLEqual(w.render('date', d), '<input type="text" name="date" value="17/09/2007 12:51:34" />')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_splithiddendatetime(self):
 | 
					    def test_splithiddendatetime(self):
 | 
				
			||||||
        from django.forms.widgets import SplitHiddenDateTimeWidget
 | 
					        from django.forms.widgets import SplitHiddenDateTimeWidget
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        w = SplitHiddenDateTimeWidget()
 | 
					        w = SplitHiddenDateTimeWidget()
 | 
				
			||||||
        self.assertHTMLEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51)), '<input type="hidden" name="date_0" value="17.09.2007" /><input type="hidden" name="date_1" value="12:51:00" />')
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            w.render('date', datetime.datetime(2007, 9, 17, 12, 51)),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <input type="hidden" name="date_0" value="17.09.2007" />
 | 
				
			||||||
 | 
					            <input type="hidden" name="date_1" value="12:51:00" />
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_nullbooleanselect(self):
 | 
					    def test_nullbooleanselect(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -1072,7 +1206,16 @@ class FormsI18NWidgetsTestCase(TestCase):
 | 
				
			||||||
        Refs #17190
 | 
					        Refs #17190
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        f = NullBooleanSelectLazyForm()
 | 
					        f = NullBooleanSelectLazyForm()
 | 
				
			||||||
        self.assertHTMLEqual(f.fields['bool'].widget.render('id_bool', True), '<select name="id_bool">\n<option value="1">Unbekannt</option>\n<option value="2" selected="selected">Ja</option>\n<option value="3">Nein</option>\n</select>')
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            f.fields['bool'].widget.render('id_bool', True),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <select name="id_bool">
 | 
				
			||||||
 | 
					                <option value="1">Unbekannt</option>
 | 
				
			||||||
 | 
					                <option value="2" selected="selected">Ja</option>
 | 
				
			||||||
 | 
					                <option value="3">Nein</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SelectAndTextWidget(MultiWidget):
 | 
					class SelectAndTextWidget(MultiWidget):
 | 
				
			||||||
| 
						 | 
					@ -1151,8 +1294,15 @@ class ClearableFileInputTests(TestCase):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        widget = ClearableFileInput()
 | 
					        widget = ClearableFileInput()
 | 
				
			||||||
        widget.is_required = False
 | 
					        widget.is_required = False
 | 
				
			||||||
        self.assertHTMLEqual(widget.render('myfile', FakeFieldFile()),
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
                         'Currently: <a href="something">something</a> <input type="checkbox" name="myfile-clear" id="myfile-clear_id" /> <label for="myfile-clear_id">Clear</label><br />Change: <input type="file" name="myfile" />')
 | 
					            widget.render('myfile', FakeFieldFile()),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            Currently: <a href="something">something</a>
 | 
				
			||||||
 | 
					            <input type="checkbox" name="myfile-clear" id="myfile-clear_id" />
 | 
				
			||||||
 | 
					            <label for="myfile-clear_id">Clear</label><br />
 | 
				
			||||||
 | 
					            Change: <input type="file" name="myfile" />
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_html_escaped(self):
 | 
					    def test_html_escaped(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -1185,8 +1335,13 @@ class ClearableFileInputTests(TestCase):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        widget = ClearableFileInput()
 | 
					        widget = ClearableFileInput()
 | 
				
			||||||
        widget.is_required = True
 | 
					        widget.is_required = True
 | 
				
			||||||
        self.assertHTMLEqual(widget.render('myfile', FakeFieldFile()),
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
                         'Currently: <a href="something">something</a> <br />Change: <input type="file" name="myfile" />')
 | 
					            widget.render('myfile', FakeFieldFile()),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            Currently: <a href="something">something</a> <br />
 | 
				
			||||||
 | 
					            Change: <input type="file" name="myfile" />
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_clear_input_renders_only_if_initial(self):
 | 
					    def test_clear_input_renders_only_if_initial(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -1238,3 +1393,567 @@ class ClearableFileInputTests(TestCase):
 | 
				
			||||||
            '<input type="checkbox" name="myfile-clear" id="myfile-clear_id" /> '
 | 
					            '<input type="checkbox" name="myfile-clear" id="myfile-clear_id" /> '
 | 
				
			||||||
            '<label for="myfile-clear_id">Clear</label><br />Change: <input type="file" name="myfile" />'
 | 
					            '<label for="myfile-clear_id">Clear</label><br />Change: <input type="file" name="myfile" />'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GetDate(Form):
 | 
				
			||||||
 | 
					    mydate = DateField(widget=SelectDateWidget)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SelectDateWidgetTests(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # The forms library comes with some extra, higher-level Field and Widget
 | 
				
			||||||
 | 
					    def test_selectdate(self):
 | 
				
			||||||
 | 
					        self.maxDiff = None
 | 
				
			||||||
 | 
					        w = SelectDateWidget(years=('2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Rendering the default state.
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            w.render('mydate', ''),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <select name="mydate_month" id="id_mydate_month">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="1">January</option>
 | 
				
			||||||
 | 
					                <option value="2">February</option>
 | 
				
			||||||
 | 
					                <option value="3">March</option>
 | 
				
			||||||
 | 
					                <option value="4">April</option>
 | 
				
			||||||
 | 
					                <option value="5">May</option>
 | 
				
			||||||
 | 
					                <option value="6">June</option>
 | 
				
			||||||
 | 
					                <option value="7">July</option>
 | 
				
			||||||
 | 
					                <option value="8">August</option>
 | 
				
			||||||
 | 
					                <option value="9">September</option>
 | 
				
			||||||
 | 
					                <option value="10">October</option>
 | 
				
			||||||
 | 
					                <option value="11">November</option>
 | 
				
			||||||
 | 
					                <option value="12">December</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="mydate_day" id="id_mydate_day">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="1">1</option>
 | 
				
			||||||
 | 
					                <option value="2">2</option>
 | 
				
			||||||
 | 
					                <option value="3">3</option>
 | 
				
			||||||
 | 
					                <option value="4">4</option>
 | 
				
			||||||
 | 
					                <option value="5">5</option>
 | 
				
			||||||
 | 
					                <option value="6">6</option>
 | 
				
			||||||
 | 
					                <option value="7">7</option>
 | 
				
			||||||
 | 
					                <option value="8">8</option>
 | 
				
			||||||
 | 
					                <option value="9">9</option>
 | 
				
			||||||
 | 
					                <option value="10">10</option>
 | 
				
			||||||
 | 
					                <option value="11">11</option>
 | 
				
			||||||
 | 
					                <option value="12">12</option>
 | 
				
			||||||
 | 
					                <option value="13">13</option>
 | 
				
			||||||
 | 
					                <option value="14">14</option>
 | 
				
			||||||
 | 
					                <option value="15">15</option>
 | 
				
			||||||
 | 
					                <option value="16">16</option>
 | 
				
			||||||
 | 
					                <option value="17">17</option>
 | 
				
			||||||
 | 
					                <option value="18">18</option>
 | 
				
			||||||
 | 
					                <option value="19">19</option>
 | 
				
			||||||
 | 
					                <option value="20">20</option>
 | 
				
			||||||
 | 
					                <option value="21">21</option>
 | 
				
			||||||
 | 
					                <option value="22">22</option>
 | 
				
			||||||
 | 
					                <option value="23">23</option>
 | 
				
			||||||
 | 
					                <option value="24">24</option>
 | 
				
			||||||
 | 
					                <option value="25">25</option>
 | 
				
			||||||
 | 
					                <option value="26">26</option>
 | 
				
			||||||
 | 
					                <option value="27">27</option>
 | 
				
			||||||
 | 
					                <option value="28">28</option>
 | 
				
			||||||
 | 
					                <option value="29">29</option>
 | 
				
			||||||
 | 
					                <option value="30">30</option>
 | 
				
			||||||
 | 
					                <option value="31">31</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="mydate_year" id="id_mydate_year">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="2007">2007</option>
 | 
				
			||||||
 | 
					                <option value="2008">2008</option>
 | 
				
			||||||
 | 
					                <option value="2009">2009</option>
 | 
				
			||||||
 | 
					                <option value="2010">2010</option>
 | 
				
			||||||
 | 
					                <option value="2011">2011</option>
 | 
				
			||||||
 | 
					                <option value="2012">2012</option>
 | 
				
			||||||
 | 
					                <option value="2013">2013</option>
 | 
				
			||||||
 | 
					                <option value="2014">2014</option>
 | 
				
			||||||
 | 
					                <option value="2015">2015</option>
 | 
				
			||||||
 | 
					                <option value="2016">2016</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Rendering the None or '' values should yield the same output.
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(w.render('mydate', None), w.render('mydate', ''))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Rendering a string value.
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            w.render('mydate', '2010-04-15'),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <select name="mydate_month" id="id_mydate_month">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="1">January</option>
 | 
				
			||||||
 | 
					                <option value="2">February</option>
 | 
				
			||||||
 | 
					                <option value="3">March</option>
 | 
				
			||||||
 | 
					                <option value="4" selected="selected">April</option>
 | 
				
			||||||
 | 
					                <option value="5">May</option>
 | 
				
			||||||
 | 
					                <option value="6">June</option>
 | 
				
			||||||
 | 
					                <option value="7">July</option>
 | 
				
			||||||
 | 
					                <option value="8">August</option>
 | 
				
			||||||
 | 
					                <option value="9">September</option>
 | 
				
			||||||
 | 
					                <option value="10">October</option>
 | 
				
			||||||
 | 
					                <option value="11">November</option>
 | 
				
			||||||
 | 
					                <option value="12">December</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="mydate_day" id="id_mydate_day">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="1">1</option>
 | 
				
			||||||
 | 
					                <option value="2">2</option>
 | 
				
			||||||
 | 
					                <option value="3">3</option>
 | 
				
			||||||
 | 
					                <option value="4">4</option>
 | 
				
			||||||
 | 
					                <option value="5">5</option>
 | 
				
			||||||
 | 
					                <option value="6">6</option>
 | 
				
			||||||
 | 
					                <option value="7">7</option>
 | 
				
			||||||
 | 
					                <option value="8">8</option>
 | 
				
			||||||
 | 
					                <option value="9">9</option>
 | 
				
			||||||
 | 
					                <option value="10">10</option>
 | 
				
			||||||
 | 
					                <option value="11">11</option>
 | 
				
			||||||
 | 
					                <option value="12">12</option>
 | 
				
			||||||
 | 
					                <option value="13">13</option>
 | 
				
			||||||
 | 
					                <option value="14">14</option>
 | 
				
			||||||
 | 
					                <option value="15" selected="selected">15</option>
 | 
				
			||||||
 | 
					                <option value="16">16</option>
 | 
				
			||||||
 | 
					                <option value="17">17</option>
 | 
				
			||||||
 | 
					                <option value="18">18</option>
 | 
				
			||||||
 | 
					                <option value="19">19</option>
 | 
				
			||||||
 | 
					                <option value="20">20</option>
 | 
				
			||||||
 | 
					                <option value="21">21</option>
 | 
				
			||||||
 | 
					                <option value="22">22</option>
 | 
				
			||||||
 | 
					                <option value="23">23</option>
 | 
				
			||||||
 | 
					                <option value="24">24</option>
 | 
				
			||||||
 | 
					                <option value="25">25</option>
 | 
				
			||||||
 | 
					                <option value="26">26</option>
 | 
				
			||||||
 | 
					                <option value="27">27</option>
 | 
				
			||||||
 | 
					                <option value="28">28</option>
 | 
				
			||||||
 | 
					                <option value="29">29</option>
 | 
				
			||||||
 | 
					                <option value="30">30</option>
 | 
				
			||||||
 | 
					                <option value="31">31</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="mydate_year" id="id_mydate_year">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="2007">2007</option>
 | 
				
			||||||
 | 
					                <option value="2008">2008</option>
 | 
				
			||||||
 | 
					                <option value="2009">2009</option>
 | 
				
			||||||
 | 
					                <option value="2010" selected="selected">2010</option>
 | 
				
			||||||
 | 
					                <option value="2011">2011</option>
 | 
				
			||||||
 | 
					                <option value="2012">2012</option>
 | 
				
			||||||
 | 
					                <option value="2013">2013</option>
 | 
				
			||||||
 | 
					                <option value="2014">2014</option>
 | 
				
			||||||
 | 
					                <option value="2015">2015</option>
 | 
				
			||||||
 | 
					                <option value="2016">2016</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Rendering a datetime value.
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(w.render('mydate', datetime.date(2010, 4, 15)), w.render('mydate', '2010-04-15'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Invalid dates should still render the failed date.
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            w.render('mydate', '2010-02-31'),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <select name="mydate_month" id="id_mydate_month">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="1">January</option>
 | 
				
			||||||
 | 
					                <option value="2" selected="selected">February</option>
 | 
				
			||||||
 | 
					                <option value="3">March</option>
 | 
				
			||||||
 | 
					                <option value="4">April</option>
 | 
				
			||||||
 | 
					                <option value="5">May</option>
 | 
				
			||||||
 | 
					                <option value="6">June</option>
 | 
				
			||||||
 | 
					                <option value="7">July</option>
 | 
				
			||||||
 | 
					                <option value="8">August</option>
 | 
				
			||||||
 | 
					                <option value="9">September</option>
 | 
				
			||||||
 | 
					                <option value="10">October</option>
 | 
				
			||||||
 | 
					                <option value="11">November</option>
 | 
				
			||||||
 | 
					                <option value="12">December</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="mydate_day" id="id_mydate_day">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="1">1</option>
 | 
				
			||||||
 | 
					                <option value="2">2</option>
 | 
				
			||||||
 | 
					                <option value="3">3</option>
 | 
				
			||||||
 | 
					                <option value="4">4</option>
 | 
				
			||||||
 | 
					                <option value="5">5</option>
 | 
				
			||||||
 | 
					                <option value="6">6</option>
 | 
				
			||||||
 | 
					                <option value="7">7</option>
 | 
				
			||||||
 | 
					                <option value="8">8</option>
 | 
				
			||||||
 | 
					                <option value="9">9</option>
 | 
				
			||||||
 | 
					                <option value="10">10</option>
 | 
				
			||||||
 | 
					                <option value="11">11</option>
 | 
				
			||||||
 | 
					                <option value="12">12</option>
 | 
				
			||||||
 | 
					                <option value="13">13</option>
 | 
				
			||||||
 | 
					                <option value="14">14</option>
 | 
				
			||||||
 | 
					                <option value="15">15</option>
 | 
				
			||||||
 | 
					                <option value="16">16</option>
 | 
				
			||||||
 | 
					                <option value="17">17</option>
 | 
				
			||||||
 | 
					                <option value="18">18</option>
 | 
				
			||||||
 | 
					                <option value="19">19</option>
 | 
				
			||||||
 | 
					                <option value="20">20</option>
 | 
				
			||||||
 | 
					                <option value="21">21</option>
 | 
				
			||||||
 | 
					                <option value="22">22</option>
 | 
				
			||||||
 | 
					                <option value="23">23</option>
 | 
				
			||||||
 | 
					                <option value="24">24</option>
 | 
				
			||||||
 | 
					                <option value="25">25</option>
 | 
				
			||||||
 | 
					                <option value="26">26</option>
 | 
				
			||||||
 | 
					                <option value="27">27</option>
 | 
				
			||||||
 | 
					                <option value="28">28</option>
 | 
				
			||||||
 | 
					                <option value="29">29</option>
 | 
				
			||||||
 | 
					                <option value="30">30</option>
 | 
				
			||||||
 | 
					                <option value="31" selected="selected">31</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="mydate_year" id="id_mydate_year">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="2007">2007</option>
 | 
				
			||||||
 | 
					                <option value="2008">2008</option>
 | 
				
			||||||
 | 
					                <option value="2009">2009</option>
 | 
				
			||||||
 | 
					                <option value="2010" selected="selected">2010</option>
 | 
				
			||||||
 | 
					                <option value="2011">2011</option>
 | 
				
			||||||
 | 
					                <option value="2012">2012</option>
 | 
				
			||||||
 | 
					                <option value="2013">2013</option>
 | 
				
			||||||
 | 
					                <option value="2014">2014</option>
 | 
				
			||||||
 | 
					                <option value="2015">2015</option>
 | 
				
			||||||
 | 
					                <option value="2016">2016</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Rendering with a custom months dict.
 | 
				
			||||||
 | 
					        w = SelectDateWidget(months=MONTHS_AP, years=('2013',))
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            w.render('mydate', ''),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <select name="mydate_month" id="id_mydate_month">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="1">Jan.</option>
 | 
				
			||||||
 | 
					                <option value="2">Feb.</option>
 | 
				
			||||||
 | 
					                <option value="3">March</option>
 | 
				
			||||||
 | 
					                <option value="4">April</option>
 | 
				
			||||||
 | 
					                <option value="5">May</option>
 | 
				
			||||||
 | 
					                <option value="6">June</option>
 | 
				
			||||||
 | 
					                <option value="7">July</option>
 | 
				
			||||||
 | 
					                <option value="8">Aug.</option>
 | 
				
			||||||
 | 
					                <option value="9">Sept.</option>
 | 
				
			||||||
 | 
					                <option value="10">Oct.</option>
 | 
				
			||||||
 | 
					                <option value="11">Nov.</option>
 | 
				
			||||||
 | 
					                <option value="12">Dec.</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="mydate_day" id="id_mydate_day">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="1">1</option>
 | 
				
			||||||
 | 
					                <option value="2">2</option>
 | 
				
			||||||
 | 
					                <option value="3">3</option>
 | 
				
			||||||
 | 
					                <option value="4">4</option>
 | 
				
			||||||
 | 
					                <option value="5">5</option>
 | 
				
			||||||
 | 
					                <option value="6">6</option>
 | 
				
			||||||
 | 
					                <option value="7">7</option>
 | 
				
			||||||
 | 
					                <option value="8">8</option>
 | 
				
			||||||
 | 
					                <option value="9">9</option>
 | 
				
			||||||
 | 
					                <option value="10">10</option>
 | 
				
			||||||
 | 
					                <option value="11">11</option>
 | 
				
			||||||
 | 
					                <option value="12">12</option>
 | 
				
			||||||
 | 
					                <option value="13">13</option>
 | 
				
			||||||
 | 
					                <option value="14">14</option>
 | 
				
			||||||
 | 
					                <option value="15">15</option>
 | 
				
			||||||
 | 
					                <option value="16">16</option>
 | 
				
			||||||
 | 
					                <option value="17">17</option>
 | 
				
			||||||
 | 
					                <option value="18">18</option>
 | 
				
			||||||
 | 
					                <option value="19">19</option>
 | 
				
			||||||
 | 
					                <option value="20">20</option>
 | 
				
			||||||
 | 
					                <option value="21">21</option>
 | 
				
			||||||
 | 
					                <option value="22">22</option>
 | 
				
			||||||
 | 
					                <option value="23">23</option>
 | 
				
			||||||
 | 
					                <option value="24">24</option>
 | 
				
			||||||
 | 
					                <option value="25">25</option>
 | 
				
			||||||
 | 
					                <option value="26">26</option>
 | 
				
			||||||
 | 
					                <option value="27">27</option>
 | 
				
			||||||
 | 
					                <option value="28">28</option>
 | 
				
			||||||
 | 
					                <option value="29">29</option>
 | 
				
			||||||
 | 
					                <option value="30">30</option>
 | 
				
			||||||
 | 
					                <option value="31">31</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="mydate_year" id="id_mydate_year">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="2013">2013</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        a = GetDate({'mydate_month': '4', 'mydate_day': '1', 'mydate_year': '2008'})
 | 
				
			||||||
 | 
					        self.assertTrue(a.is_valid())
 | 
				
			||||||
 | 
					        self.assertEqual(a.cleaned_data['mydate'], datetime.date(2008, 4, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # As with any widget that implements get_value_from_datadict,
 | 
				
			||||||
 | 
					        # we must be prepared to accept the input from the "as_hidden"
 | 
				
			||||||
 | 
					        # rendering as well.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            a['mydate'].as_hidden(),
 | 
				
			||||||
 | 
					            '<input type="hidden" name="mydate" value="2008-4-1" id="id_mydate" />',
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b = GetDate({'mydate': '2008-4-1'})
 | 
				
			||||||
 | 
					        self.assertTrue(b.is_valid())
 | 
				
			||||||
 | 
					        self.assertEqual(b.cleaned_data['mydate'], datetime.date(2008, 4, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Invalid dates shouldn't be allowed
 | 
				
			||||||
 | 
					        c = GetDate({'mydate_month': '2', 'mydate_day': '31', 'mydate_year': '2010'})
 | 
				
			||||||
 | 
					        self.assertFalse(c.is_valid())
 | 
				
			||||||
 | 
					        self.assertEqual(c.errors, {'mydate': ['Enter a valid date.']})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # label tag is correctly associated with month dropdown
 | 
				
			||||||
 | 
					        d = GetDate({'mydate_month': '1', 'mydate_day': '1', 'mydate_year': '2010'})
 | 
				
			||||||
 | 
					        self.assertIn('<label for="id_mydate_month">', d.as_p())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_selectdate_required(self):
 | 
				
			||||||
 | 
					        class GetNotRequiredDate(Form):
 | 
				
			||||||
 | 
					            mydate = DateField(widget=SelectDateWidget, required=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class GetRequiredDate(Form):
 | 
				
			||||||
 | 
					            mydate = DateField(widget=SelectDateWidget, required=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertFalse(GetNotRequiredDate().fields['mydate'].widget.is_required)
 | 
				
			||||||
 | 
					        self.assertTrue(GetRequiredDate().fields['mydate'].widget.is_required)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_selectdate_empty_label(self):
 | 
				
			||||||
 | 
					        w = SelectDateWidget(years=('2014',), empty_label='empty_label')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Rendering the default state with empty_label setted as string.
 | 
				
			||||||
 | 
					        self.assertInHTML('<option value="0">empty_label</option>', w.render('mydate', ''), count=3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        w = SelectDateWidget(years=('2014',), empty_label=('empty_year', 'empty_month', 'empty_day'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Rendering the default state with empty_label tuple.
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            w.render('mydate', ''),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <select name="mydate_month" id="id_mydate_month">
 | 
				
			||||||
 | 
					                <option value="0">empty_month</option>
 | 
				
			||||||
 | 
					                <option value="1">January</option>
 | 
				
			||||||
 | 
					                <option value="2">February</option>
 | 
				
			||||||
 | 
					                <option value="3">March</option>
 | 
				
			||||||
 | 
					                <option value="4">April</option>
 | 
				
			||||||
 | 
					                <option value="5">May</option>
 | 
				
			||||||
 | 
					                <option value="6">June</option>
 | 
				
			||||||
 | 
					                <option value="7">July</option>
 | 
				
			||||||
 | 
					                <option value="8">August</option>
 | 
				
			||||||
 | 
					                <option value="9">September</option>
 | 
				
			||||||
 | 
					                <option value="10">October</option>
 | 
				
			||||||
 | 
					                <option value="11">November</option>
 | 
				
			||||||
 | 
					                <option value="12">December</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="mydate_day" id="id_mydate_day">
 | 
				
			||||||
 | 
					                <option value="0">empty_day</option>
 | 
				
			||||||
 | 
					                <option value="1">1</option>
 | 
				
			||||||
 | 
					                <option value="2">2</option>
 | 
				
			||||||
 | 
					                <option value="3">3</option>
 | 
				
			||||||
 | 
					                <option value="4">4</option>
 | 
				
			||||||
 | 
					                <option value="5">5</option>
 | 
				
			||||||
 | 
					                <option value="6">6</option>
 | 
				
			||||||
 | 
					                <option value="7">7</option>
 | 
				
			||||||
 | 
					                <option value="8">8</option>
 | 
				
			||||||
 | 
					                <option value="9">9</option>
 | 
				
			||||||
 | 
					                <option value="10">10</option>
 | 
				
			||||||
 | 
					                <option value="11">11</option>
 | 
				
			||||||
 | 
					                <option value="12">12</option>
 | 
				
			||||||
 | 
					                <option value="13">13</option>
 | 
				
			||||||
 | 
					                <option value="14">14</option>
 | 
				
			||||||
 | 
					                <option value="15">15</option>
 | 
				
			||||||
 | 
					                <option value="16">16</option>
 | 
				
			||||||
 | 
					                <option value="17">17</option>
 | 
				
			||||||
 | 
					                <option value="18">18</option>
 | 
				
			||||||
 | 
					                <option value="19">19</option>
 | 
				
			||||||
 | 
					                <option value="20">20</option>
 | 
				
			||||||
 | 
					                <option value="21">21</option>
 | 
				
			||||||
 | 
					                <option value="22">22</option>
 | 
				
			||||||
 | 
					                <option value="23">23</option>
 | 
				
			||||||
 | 
					                <option value="24">24</option>
 | 
				
			||||||
 | 
					                <option value="25">25</option>
 | 
				
			||||||
 | 
					                <option value="26">26</option>
 | 
				
			||||||
 | 
					                <option value="27">27</option>
 | 
				
			||||||
 | 
					                <option value="28">28</option>
 | 
				
			||||||
 | 
					                <option value="29">29</option>
 | 
				
			||||||
 | 
					                <option value="30">30</option>
 | 
				
			||||||
 | 
					                <option value="31">31</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="mydate_year" id="id_mydate_year">
 | 
				
			||||||
 | 
					                <option value="0">empty_year</option>
 | 
				
			||||||
 | 
					                <option value="2014">2014</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertRaisesMessage(ValueError, 'empty_label list/tuple must have 3 elements.',
 | 
				
			||||||
 | 
					            SelectDateWidget, years=('2014',), empty_label=('not enough', 'values'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @override_settings(USE_L10N=True)
 | 
				
			||||||
 | 
					    @translation.override('nl')
 | 
				
			||||||
 | 
					    def test_l10n(self):
 | 
				
			||||||
 | 
					        w = SelectDateWidget(years=('2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016'))
 | 
				
			||||||
 | 
					        self.assertEqual(
 | 
				
			||||||
 | 
					            w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date'),
 | 
				
			||||||
 | 
					            '13-08-2010',
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertHTMLEqual(
 | 
				
			||||||
 | 
					            w.render('date', '13-08-2010'),
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					            <select name="date_day" id="id_date_day">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="1">1</option>
 | 
				
			||||||
 | 
					                <option value="2">2</option>
 | 
				
			||||||
 | 
					                <option value="3">3</option>
 | 
				
			||||||
 | 
					                <option value="4">4</option>
 | 
				
			||||||
 | 
					                <option value="5">5</option>
 | 
				
			||||||
 | 
					                <option value="6">6</option>
 | 
				
			||||||
 | 
					                <option value="7">7</option>
 | 
				
			||||||
 | 
					                <option value="8">8</option>
 | 
				
			||||||
 | 
					                <option value="9">9</option>
 | 
				
			||||||
 | 
					                <option value="10">10</option>
 | 
				
			||||||
 | 
					                <option value="11">11</option>
 | 
				
			||||||
 | 
					                <option value="12">12</option>
 | 
				
			||||||
 | 
					                <option value="13" selected="selected">13</option>
 | 
				
			||||||
 | 
					                <option value="14">14</option>
 | 
				
			||||||
 | 
					                <option value="15">15</option>
 | 
				
			||||||
 | 
					                <option value="16">16</option>
 | 
				
			||||||
 | 
					                <option value="17">17</option>
 | 
				
			||||||
 | 
					                <option value="18">18</option>
 | 
				
			||||||
 | 
					                <option value="19">19</option>
 | 
				
			||||||
 | 
					                <option value="20">20</option>
 | 
				
			||||||
 | 
					                <option value="21">21</option>
 | 
				
			||||||
 | 
					                <option value="22">22</option>
 | 
				
			||||||
 | 
					                <option value="23">23</option>
 | 
				
			||||||
 | 
					                <option value="24">24</option>
 | 
				
			||||||
 | 
					                <option value="25">25</option>
 | 
				
			||||||
 | 
					                <option value="26">26</option>
 | 
				
			||||||
 | 
					                <option value="27">27</option>
 | 
				
			||||||
 | 
					                <option value="28">28</option>
 | 
				
			||||||
 | 
					                <option value="29">29</option>
 | 
				
			||||||
 | 
					                <option value="30">30</option>
 | 
				
			||||||
 | 
					                <option value="31">31</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="date_month" id="id_date_month">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="1">januari</option>
 | 
				
			||||||
 | 
					                <option value="2">februari</option>
 | 
				
			||||||
 | 
					                <option value="3">maart</option>
 | 
				
			||||||
 | 
					                <option value="4">april</option>
 | 
				
			||||||
 | 
					                <option value="5">mei</option>
 | 
				
			||||||
 | 
					                <option value="6">juni</option>
 | 
				
			||||||
 | 
					                <option value="7">juli</option>
 | 
				
			||||||
 | 
					                <option value="8" selected="selected">augustus</option>
 | 
				
			||||||
 | 
					                <option value="9">september</option>
 | 
				
			||||||
 | 
					                <option value="10">oktober</option>
 | 
				
			||||||
 | 
					                <option value="11">november</option>
 | 
				
			||||||
 | 
					                <option value="12">december</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <select name="date_year" id="id_date_year">
 | 
				
			||||||
 | 
					                <option value="0">---</option>
 | 
				
			||||||
 | 
					                <option value="2007">2007</option>
 | 
				
			||||||
 | 
					                <option value="2008">2008</option>
 | 
				
			||||||
 | 
					                <option value="2009">2009</option>
 | 
				
			||||||
 | 
					                <option value="2010" selected="selected">2010</option>
 | 
				
			||||||
 | 
					                <option value="2011">2011</option>
 | 
				
			||||||
 | 
					                <option value="2012">2012</option>
 | 
				
			||||||
 | 
					                <option value="2013">2013</option>
 | 
				
			||||||
 | 
					                <option value="2014">2014</option>
 | 
				
			||||||
 | 
					                <option value="2015">2015</option>
 | 
				
			||||||
 | 
					                <option value="2016">2016</option>
 | 
				
			||||||
 | 
					            </select>
 | 
				
			||||||
 | 
					            """,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Years before 1900 work
 | 
				
			||||||
 | 
					        w = SelectDateWidget(years=('1899',))
 | 
				
			||||||
 | 
					        self.assertEqual(
 | 
				
			||||||
 | 
					            w.value_from_datadict({'date_year': '1899', 'date_month': '8', 'date_day': '13'}, {}, 'date'),
 | 
				
			||||||
 | 
					            '13-08-1899',
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @override_settings(USE_L10N=True)
 | 
				
			||||||
 | 
					    @translation.override('nl')
 | 
				
			||||||
 | 
					    def test_l10n_date_changed(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Ensure that DateField.has_changed() with SelectDateWidget works
 | 
				
			||||||
 | 
					        correctly with a localized date format.
 | 
				
			||||||
 | 
					        Refs #17165.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        # With Field.show_hidden_initial=False -----------------------
 | 
				
			||||||
 | 
					        b = GetDate({
 | 
				
			||||||
 | 
					            'mydate_year': '2008',
 | 
				
			||||||
 | 
					            'mydate_month': '4',
 | 
				
			||||||
 | 
					            'mydate_day': '1',
 | 
				
			||||||
 | 
					        }, initial={'mydate': datetime.date(2008, 4, 1)})
 | 
				
			||||||
 | 
					        self.assertFalse(b.has_changed())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b = GetDate({
 | 
				
			||||||
 | 
					            'mydate_year': '2008',
 | 
				
			||||||
 | 
					            'mydate_month': '4',
 | 
				
			||||||
 | 
					            'mydate_day': '2',
 | 
				
			||||||
 | 
					        }, initial={'mydate': datetime.date(2008, 4, 1)})
 | 
				
			||||||
 | 
					        self.assertTrue(b.has_changed())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # With Field.show_hidden_initial=True ------------------------
 | 
				
			||||||
 | 
					        class GetDateShowHiddenInitial(Form):
 | 
				
			||||||
 | 
					            mydate = DateField(widget=SelectDateWidget, show_hidden_initial=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b = GetDateShowHiddenInitial({
 | 
				
			||||||
 | 
					            'mydate_year': '2008',
 | 
				
			||||||
 | 
					            'mydate_month': '4',
 | 
				
			||||||
 | 
					            'mydate_day': '1',
 | 
				
			||||||
 | 
					            'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 1))
 | 
				
			||||||
 | 
					        }, initial={'mydate': datetime.date(2008, 4, 1)})
 | 
				
			||||||
 | 
					        self.assertFalse(b.has_changed())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b = GetDateShowHiddenInitial({
 | 
				
			||||||
 | 
					            'mydate_year': '2008',
 | 
				
			||||||
 | 
					            'mydate_month': '4',
 | 
				
			||||||
 | 
					            'mydate_day': '22',
 | 
				
			||||||
 | 
					            'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 1))
 | 
				
			||||||
 | 
					        }, initial={'mydate': datetime.date(2008, 4, 1)})
 | 
				
			||||||
 | 
					        self.assertTrue(b.has_changed())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b = GetDateShowHiddenInitial({
 | 
				
			||||||
 | 
					            'mydate_year': '2008',
 | 
				
			||||||
 | 
					            'mydate_month': '4',
 | 
				
			||||||
 | 
					            'mydate_day': '22',
 | 
				
			||||||
 | 
					            'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 1))
 | 
				
			||||||
 | 
					        }, initial={'mydate': datetime.date(2008, 4, 22)})
 | 
				
			||||||
 | 
					        self.assertTrue(b.has_changed())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b = GetDateShowHiddenInitial({
 | 
				
			||||||
 | 
					            'mydate_year': '2008',
 | 
				
			||||||
 | 
					            'mydate_month': '4',
 | 
				
			||||||
 | 
					            'mydate_day': '22',
 | 
				
			||||||
 | 
					            'initial-mydate': HiddenInput()._format_value(datetime.date(2008, 4, 22))
 | 
				
			||||||
 | 
					        }, initial={'mydate': datetime.date(2008, 4, 1)})
 | 
				
			||||||
 | 
					        self.assertFalse(b.has_changed())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @override_settings(USE_L10N=True)
 | 
				
			||||||
 | 
					    @translation.override('nl')
 | 
				
			||||||
 | 
					    def test_l10n_invalid_date_in(self):
 | 
				
			||||||
 | 
					        # Invalid dates shouldn't be allowed
 | 
				
			||||||
 | 
					        a = GetDate({'mydate_month': '2', 'mydate_day': '31', 'mydate_year': '2010'})
 | 
				
			||||||
 | 
					        self.assertFalse(a.is_valid())
 | 
				
			||||||
 | 
					        # 'Geef een geldige datum op.' = 'Enter a valid date.'
 | 
				
			||||||
 | 
					        self.assertEqual(a.errors, {'mydate': ['Geef een geldige datum op.']})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @override_settings(USE_L10N=True)
 | 
				
			||||||
 | 
					    @translation.override('nl')
 | 
				
			||||||
 | 
					    def test_form_label_association(self):
 | 
				
			||||||
 | 
					        # label tag is correctly associated with first rendered dropdown
 | 
				
			||||||
 | 
					        a = GetDate({'mydate_month': '1', 'mydate_day': '1', 'mydate_year': '2010'})
 | 
				
			||||||
 | 
					        self.assertIn('<label for="id_mydate_day">', a.as_p())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@ import datetime
 | 
				
			||||||
from django.utils import six
 | 
					from django.utils import six
 | 
				
			||||||
from django.utils.encoding import (
 | 
					from django.utils.encoding import (
 | 
				
			||||||
    filepath_to_uri, force_bytes, force_text, escape_uri_path,
 | 
					    filepath_to_uri, force_bytes, force_text, escape_uri_path,
 | 
				
			||||||
    iri_to_uri, uri_to_iri,
 | 
					    iri_to_uri, uri_to_iri, smart_text,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from django.utils.http import urlquote_plus
 | 
					from django.utils.http import urlquote_plus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,13 +42,33 @@ class TestEncodingUtils(unittest.TestCase):
 | 
				
			||||||
        today = datetime.date.today()
 | 
					        today = datetime.date.today()
 | 
				
			||||||
        self.assertEqual(force_bytes(today, strings_only=True), today)
 | 
					        self.assertEqual(force_bytes(today, strings_only=True), today)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_escape_uri_path(self):
 | 
					    def test_smart_text(self):
 | 
				
			||||||
        self.assertEqual(
 | 
					        class Test:
 | 
				
			||||||
            escape_uri_path('/;some/=awful/?path/:with/@lots/&of/+awful/chars'),
 | 
					            if six.PY3:
 | 
				
			||||||
            '/%3Bsome/%3Dawful/%3Fpath/:with/@lots/&of/+awful/chars'
 | 
					                def __str__(self):
 | 
				
			||||||
        )
 | 
					                    return 'ŠĐĆŽćžšđ'
 | 
				
			||||||
        self.assertEqual(escape_uri_path('/foo#bar'), '/foo%23bar')
 | 
					            else:
 | 
				
			||||||
        self.assertEqual(escape_uri_path('/foo?bar'), '/foo%3Fbar')
 | 
					                def __str__(self):
 | 
				
			||||||
 | 
					                    return 'ŠĐĆŽćžšđ'.encode('utf-8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class TestU:
 | 
				
			||||||
 | 
					            if six.PY3:
 | 
				
			||||||
 | 
					                def __str__(self):
 | 
				
			||||||
 | 
					                    return 'ŠĐĆŽćžšđ'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                def __bytes__(self):
 | 
				
			||||||
 | 
					                    return b'Foo'
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                def __str__(self):
 | 
				
			||||||
 | 
					                    return b'Foo'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                def __unicode__(self):
 | 
				
			||||||
 | 
					                    return '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(smart_text(Test()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
 | 
				
			||||||
 | 
					        self.assertEqual(smart_text(TestU()), '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
 | 
				
			||||||
 | 
					        self.assertEqual(smart_text(1), '1')
 | 
				
			||||||
 | 
					        self.assertEqual(smart_text('foo'), 'foo')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestRFC3987IEncodingUtils(unittest.TestCase):
 | 
					class TestRFC3987IEncodingUtils(unittest.TestCase):
 | 
				
			||||||
| 
						 | 
					@ -114,3 +134,11 @@ class TestRFC3987IEncodingUtils(unittest.TestCase):
 | 
				
			||||||
        for uri, iri in cases:
 | 
					        for uri, iri in cases:
 | 
				
			||||||
            self.assertEqual(iri_to_uri(uri_to_iri(uri)), uri)
 | 
					            self.assertEqual(iri_to_uri(uri_to_iri(uri)), uri)
 | 
				
			||||||
            self.assertEqual(uri_to_iri(iri_to_uri(iri)), iri)
 | 
					            self.assertEqual(uri_to_iri(iri_to_uri(iri)), iri)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_escape_uri_path(self):
 | 
				
			||||||
 | 
					        self.assertEqual(
 | 
				
			||||||
 | 
					            escape_uri_path('/;some/=awful/?path/:with/@lots/&of/+awful/chars'),
 | 
				
			||||||
 | 
					            '/%3Bsome/%3Dawful/%3Fpath/:with/@lots/&of/+awful/chars'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(escape_uri_path('/foo#bar'), '/foo%23bar')
 | 
				
			||||||
 | 
					        self.assertEqual(escape_uri_path('/foo?bar'), '/foo%3Fbar')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue