Code

Ticket #13621: t13621-alternative5.diff

File t13621-alternative5.diff, 42.0 KB (added by russellm, 4 years ago)

Another alternative, this time preserving the isolation of input_formats on Field.

Line 
1diff -r b2f7c125865a django/forms/widgets.py
2--- a/django/forms/widgets.py   Fri Jul 30 04:15:16 2010 +0000
3+++ b/django/forms/widgets.py   Wed Aug 04 15:29:56 2010 +0800
4@@ -308,9 +308,13 @@
5         super(DateInput, self).__init__(attrs)
6         if format:
7             self.format = format
8+            self.manual_format = True
9+        else:
10+            self.format = formats.get_format('DATE_INPUT_FORMATS')[0]
11+            self.manual_format = False
12 
13     def _format_value(self, value):
14-        if self.is_localized:
15+        if self.is_localized and not self.manual_format:
16             return formats.localize_input(value)
17         elif hasattr(value, 'strftime'):
18             value = datetime_safe.new_date(value)
19@@ -336,9 +340,13 @@
20         super(DateTimeInput, self).__init__(attrs)
21         if format:
22             self.format = format
23+            self.manual_format = True
24+        else:
25+            self.format = formats.get_format('DATETIME_INPUT_FORMATS')[0]
26+            self.manual_format = False
27 
28     def _format_value(self, value):
29-        if self.is_localized:
30+        if self.is_localized and not self.manual_format:
31             return formats.localize_input(value)
32         elif hasattr(value, 'strftime'):
33             value = datetime_safe.new_datetime(value)
34@@ -364,9 +372,13 @@
35         super(TimeInput, self).__init__(attrs)
36         if format:
37             self.format = format
38+            self.manual_format = True
39+        else:
40+            self.format = formats.get_format('TIME_INPUT_FORMATS')[0]
41+            self.manual_format = False
42 
43     def _format_value(self, value):
44-        if self.is_localized:
45+        if self.is_localized and not self.manual_format:
46             return formats.localize_input(value)
47         elif hasattr(value, 'strftime'):
48             return value.strftime(self.format)
49@@ -751,12 +763,8 @@
50     time_format = TimeInput.format
51 
52     def __init__(self, attrs=None, date_format=None, time_format=None):
53-        if date_format:
54-            self.date_format = date_format
55-        if time_format:
56-            self.time_format = time_format
57-        widgets = (DateInput(attrs=attrs, format=self.date_format),
58-                   TimeInput(attrs=attrs, format=self.time_format))
59+        widgets = (DateInput(attrs=attrs, format=date_format),
60+                   TimeInput(attrs=attrs, format=time_format))
61         super(SplitDateTimeWidget, self).__init__(widgets, attrs)
62 
63     def decompress(self, value):
64diff -r b2f7c125865a tests/regressiontests/forms/input_formats.py
65--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
66+++ b/tests/regressiontests/forms/input_formats.py      Wed Aug 04 15:29:56 2010 +0800
67@@ -0,0 +1,894 @@
68+from datetime import time, date, datetime
69+from unittest import TestCase
70+
71+from django import forms
72+from django.conf import settings
73+from django.utils.translation import activate, deactivate
74+
75+
76+class LocalizedTimeTests(TestCase):
77+    def setUp(self):
78+        self.old_TIME_INPUT_FORMATS = settings.TIME_INPUT_FORMATS
79+        self.old_USE_L10N = settings.USE_L10N
80+
81+        settings.TIME_INPUT_FORMATS = ["%I:%M:%S %p", "%I:%M %p"]
82+        settings.USE_L10N = True
83+
84+        activate('de')
85+
86+    def tearDown(self):
87+        settings.TIME_INPUT_FORMATS = self.old_TIME_INPUT_FORMATS
88+        settings.USE_L10N = self.old_USE_L10N
89+
90+        deactivate()
91+
92+    def test_timeField(self):
93+        "TimeFields can parse dates in the default format"
94+        f = forms.TimeField()
95+        # Parse a time in an unaccepted format; get an error
96+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
97+
98+        # Parse a time in a valid format, get a parsed result
99+        result = f.clean('13:30:05')
100+        self.assertEqual(result, time(13,30,5))
101+
102+        # Check that the parsed result does a round trip
103+        text = f.widget._format_value(result)
104+        self.assertEqual(text, '13:30:05')
105+
106+        # Parse a time in a valid, but non-default format, get a parsed result
107+        result = f.clean('13:30')
108+        self.assertEqual(result, time(13,30,0))
109+
110+        # Check that the parsed result does a round trip to default format
111+        text = f.widget._format_value(result)
112+        self.assertEqual(text, "13:30:00")
113+
114+    def test_localized_timeField(self):
115+        "Localized TimeFields act as unlocalized widgets"
116+        f = forms.TimeField(localize=True)
117+        # Parse a time in an unaccepted format; get an error
118+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
119+
120+        # Parse a time in a valid format, get a parsed result
121+        result = f.clean('13:30:05')
122+        self.assertEqual(result, time(13,30,5))
123+
124+        # Check that the parsed result does a round trip to the same format
125+        text = f.widget._format_value(result)
126+        self.assertEqual(text, '13:30:05')
127+
128+        # Parse a time in a valid format, get a parsed result
129+        result = f.clean('13:30')
130+        self.assertEqual(result, time(13,30,0))
131+
132+        # Check that the parsed result does a round trip to default format
133+        text = f.widget._format_value(result)
134+        self.assertEqual(text, "13:30:00")
135+
136+    def test_timeField_with_inputformat(self):
137+        "TimeFields with manually specified input formats can accept those formats"
138+        f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"])
139+        # Parse a time in an unaccepted format; get an error
140+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
141+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
142+
143+        # Parse a time in a valid format, get a parsed result
144+        result = f.clean('13.30.05')
145+        self.assertEqual(result, time(13,30,5))
146+
147+        # Check that the parsed result does a round trip to the same format
148+        text = f.widget._format_value(result)
149+        self.assertEqual(text, "13:30:05")
150+
151+        # Parse a time in a valid format, get a parsed result
152+        result = f.clean('13.30')
153+        self.assertEqual(result, time(13,30,0))
154+
155+        # Check that the parsed result does a round trip to default format
156+        text = f.widget._format_value(result)
157+        self.assertEqual(text, "13:30:00")
158+
159+    def test_localized_timeField_with_inputformat(self):
160+        "Localized TimeFields with manually specified input formats can accept those formats"
161+        f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"], localize=True)
162+        # Parse a time in an unaccepted format; get an error
163+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
164+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
165+
166+        # Parse a time in a valid format, get a parsed result
167+        result = f.clean('13.30.05')
168+        self.assertEqual(result, time(13,30,5))
169+
170+        # # Check that the parsed result does a round trip to the same format
171+        text = f.widget._format_value(result)
172+        self.assertEqual(text, "13:30:05")
173+
174+        # Parse a time in a valid format, get a parsed result
175+        result = f.clean('13.30')
176+        self.assertEqual(result, time(13,30,0))
177+
178+        # Check that the parsed result does a round trip to default format
179+        text = f.widget._format_value(result)
180+        self.assertEqual(text, "13:30:00")
181+
182+
183+class CustomTimeInputFormatsTests(TestCase):
184+    def setUp(self):
185+        self.old_TIME_INPUT_FORMATS = settings.TIME_INPUT_FORMATS
186+        settings.TIME_INPUT_FORMATS = ["%I:%M:%S %p", "%I:%M %p"]
187+
188+    def tearDown(self):
189+        settings.TIME_INPUT_FORMATS = self.old_TIME_INPUT_FORMATS
190+
191+    def test_timeField(self):
192+        "TimeFields can parse dates in the default format"
193+        f = forms.TimeField()
194+        # Parse a time in an unaccepted format; get an error
195+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
196+
197+        # Parse a time in a valid format, get a parsed result
198+        result = f.clean('1:30:05 PM')
199+        self.assertEqual(result, time(13,30,5))
200+
201+        # Check that the parsed result does a round trip
202+        text = f.widget._format_value(result)
203+        self.assertEqual(text, '01:30:05 PM')
204+
205+        # Parse a time in a valid, but non-default format, get a parsed result
206+        result = f.clean('1:30 PM')
207+        self.assertEqual(result, time(13,30,0))
208+
209+        # Check that the parsed result does a round trip to default format
210+        text = f.widget._format_value(result)
211+        self.assertEqual(text, "01:30:00 PM")
212+
213+    def test_localized_timeField(self):
214+        "Localized TimeFields act as unlocalized widgets"
215+        f = forms.TimeField(localize=True)
216+        # Parse a time in an unaccepted format; get an error
217+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
218+
219+        # Parse a time in a valid format, get a parsed result
220+        result = f.clean('1:30:05 PM')
221+        self.assertEqual(result, time(13,30,5))
222+
223+        # Check that the parsed result does a round trip to the same format
224+        text = f.widget._format_value(result)
225+        self.assertEqual(text, '01:30:05 PM')
226+
227+        # Parse a time in a valid format, get a parsed result
228+        result = f.clean('01:30 PM')
229+        self.assertEqual(result, time(13,30,0))
230+
231+        # Check that the parsed result does a round trip to default format
232+        text = f.widget._format_value(result)
233+        self.assertEqual(text, "01:30:00 PM")
234+
235+    def test_timeField_with_inputformat(self):
236+        "TimeFields with manually specified input formats can accept those formats"
237+        f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"])
238+        # Parse a time in an unaccepted format; get an error
239+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
240+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
241+
242+        # Parse a time in a valid format, get a parsed result
243+        result = f.clean('13.30.05')
244+        self.assertEqual(result, time(13,30,5))
245+
246+        # Check that the parsed result does a round trip to the same format
247+        text = f.widget._format_value(result)
248+        self.assertEqual(text, "01:30:05 PM")
249+
250+        # Parse a time in a valid format, get a parsed result
251+        result = f.clean('13.30')
252+        self.assertEqual(result, time(13,30,0))
253+
254+        # Check that the parsed result does a round trip to default format
255+        text = f.widget._format_value(result)
256+        self.assertEqual(text, "01:30:00 PM")
257+
258+    def test_localized_timeField_with_inputformat(self):
259+        "Localized TimeFields with manually specified input formats can accept those formats"
260+        f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"], localize=True)
261+        # Parse a time in an unaccepted format; get an error
262+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
263+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
264+
265+        # Parse a time in a valid format, get a parsed result
266+        result = f.clean('13.30.05')
267+        self.assertEqual(result, time(13,30,5))
268+
269+        # # Check that the parsed result does a round trip to the same format
270+        text = f.widget._format_value(result)
271+        self.assertEqual(text, "01:30:05 PM")
272+
273+        # Parse a time in a valid format, get a parsed result
274+        result = f.clean('13.30')
275+        self.assertEqual(result, time(13,30,0))
276+
277+        # Check that the parsed result does a round trip to default format
278+        text = f.widget._format_value(result)
279+        self.assertEqual(text, "01:30:00 PM")
280+
281+
282+class SimpleTimeFormatTests(TestCase):
283+    def test_timeField(self):
284+        "TimeFields can parse dates in the default format"
285+        f = forms.TimeField()
286+        # Parse a time in an unaccepted format; get an error
287+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
288+
289+        # Parse a time in a valid format, get a parsed result
290+        result = f.clean('13:30:05')
291+        self.assertEqual(result, time(13,30,5))
292+
293+        # Check that the parsed result does a round trip to the same format
294+        text = f.widget._format_value(result)
295+        self.assertEqual(text, "13:30:05")
296+
297+        # Parse a time in a valid, but non-default format, get a parsed result
298+        result = f.clean('13:30')
299+        self.assertEqual(result, time(13,30,0))
300+
301+        # Check that the parsed result does a round trip to default format
302+        text = f.widget._format_value(result)
303+        self.assertEqual(text, "13:30:00")
304+
305+    def test_localized_timeField(self):
306+        "Localized TimeFields in a non-localized environment act as unlocalized widgets"
307+        f = forms.TimeField()
308+        # Parse a time in an unaccepted format; get an error
309+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
310+
311+        # Parse a time in a valid format, get a parsed result
312+        result = f.clean('13:30:05')
313+        self.assertEqual(result, time(13,30,5))
314+
315+        # Check that the parsed result does a round trip to the same format
316+        text = f.widget._format_value(result)
317+        self.assertEqual(text, "13:30:05")
318+
319+        # Parse a time in a valid format, get a parsed result
320+        result = f.clean('13:30')
321+        self.assertEqual(result, time(13,30,0))
322+
323+        # Check that the parsed result does a round trip to default format
324+        text = f.widget._format_value(result)
325+        self.assertEqual(text, "13:30:00")
326+
327+    def test_timeField_with_inputformat(self):
328+        "TimeFields with manually specified input formats can accept those formats"
329+        f = forms.TimeField(input_formats=["%I:%M:%S %p", "%I:%M %p"])
330+        # Parse a time in an unaccepted format; get an error
331+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
332+
333+        # Parse a time in a valid format, get a parsed result
334+        result = f.clean('1:30:05 PM')
335+        self.assertEqual(result, time(13,30,5))
336+
337+        # Check that the parsed result does a round trip to the same format
338+        text = f.widget._format_value(result)
339+        self.assertEqual(text, "13:30:05")
340+
341+        # Parse a time in a valid format, get a parsed result
342+        result = f.clean('1:30 PM')
343+        self.assertEqual(result, time(13,30,0))
344+
345+        # Check that the parsed result does a round trip to default format
346+        text = f.widget._format_value(result)
347+        self.assertEqual(text, "13:30:00")
348+
349+    def test_localized_timeField_with_inputformat(self):
350+        "Localized TimeFields with manually specified input formats can accept those formats"
351+        f = forms.TimeField(input_formats=["%I:%M:%S %p", "%I:%M %p"], localize=True)
352+        # Parse a time in an unaccepted format; get an error
353+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
354+
355+        # Parse a time in a valid format, get a parsed result
356+        result = f.clean('1:30:05 PM')
357+        self.assertEqual(result, time(13,30,5))
358+
359+        # Check that the parsed result does a round trip to the same format
360+        text = f.widget._format_value(result)
361+        self.assertEqual(text, "13:30:05")
362+
363+        # Parse a time in a valid format, get a parsed result
364+        result = f.clean('1:30 PM')
365+        self.assertEqual(result, time(13,30,0))
366+
367+        # Check that the parsed result does a round trip to default format
368+        text = f.widget._format_value(result)
369+        self.assertEqual(text, "13:30:00")
370+
371+
372+class LocalizedDateTests(TestCase):
373+    def setUp(self):
374+        self.old_DATE_INPUT_FORMATS = settings.DATE_INPUT_FORMATS
375+        self.old_USE_L10N = settings.USE_L10N
376+
377+        settings.DATE_INPUT_FORMATS = ["%d/%m/%Y", "%d-%m-%Y"]
378+        settings.USE_L10N = True
379+
380+        activate('de')
381+
382+    def tearDown(self):
383+        settings.DATE_INPUT_FORMATS = self.old_DATE_INPUT_FORMATS
384+        settings.USE_L10N = self.old_USE_L10N
385+
386+        deactivate()
387+
388+    def test_dateField(self):
389+        "DateFields can parse dates in the default format"
390+        f = forms.DateField()
391+        # Parse a date in an unaccepted format; get an error
392+        self.assertRaises(forms.ValidationError, f.clean, '21/12/2010')
393+
394+        # Parse a date in a valid format, get a parsed result
395+        result = f.clean('21.12.2010')
396+        self.assertEqual(result, date(2010,12,21))
397+
398+        # Check that the parsed result does a round trip
399+        text = f.widget._format_value(result)
400+        self.assertEqual(text, '21.12.2010')
401+
402+        # Parse a date in a valid, but non-default format, get a parsed result
403+        result = f.clean('21.12.10')
404+        self.assertEqual(result, date(2010,12,21))
405+
406+        # Check that the parsed result does a round trip to default format
407+        text = f.widget._format_value(result)
408+        self.assertEqual(text, "21.12.2010")
409+
410+    def test_localized_dateField(self):
411+        "Localized DateFields act as unlocalized widgets"
412+        f = forms.DateField(localize=True)
413+        # Parse a date in an unaccepted format; get an error
414+        self.assertRaises(forms.ValidationError, f.clean, '21/12/2010')
415+
416+        # Parse a date in a valid format, get a parsed result
417+        result = f.clean('21.12.2010')
418+        self.assertEqual(result, date(2010,12,21))
419+
420+        # Check that the parsed result does a round trip to the same format
421+        text = f.widget._format_value(result)
422+        self.assertEqual(text, '21.12.2010')
423+
424+        # Parse a date in a valid format, get a parsed result
425+        result = f.clean('21.12.10')
426+        self.assertEqual(result, date(2010,12,21))
427+
428+        # Check that the parsed result does a round trip to default format
429+        text = f.widget._format_value(result)
430+        self.assertEqual(text, "21.12.2010")
431+
432+    def test_dateField_with_inputformat(self):
433+        "DateFields with manually specified input formats can accept those formats"
434+        f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"])
435+        # Parse a date in an unaccepted format; get an error
436+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
437+        self.assertRaises(forms.ValidationError, f.clean, '21/12/2010')
438+        self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
439+
440+        # Parse a date in a valid format, get a parsed result
441+        result = f.clean('12.21.2010')
442+        self.assertEqual(result, date(2010,12,21))
443+
444+        # Check that the parsed result does a round trip to the same format
445+        text = f.widget._format_value(result)
446+        self.assertEqual(text, "21.12.2010")
447+
448+        # Parse a date in a valid format, get a parsed result
449+        result = f.clean('12-21-2010')
450+        self.assertEqual(result, date(2010,12,21))
451+
452+        # Check that the parsed result does a round trip to default format
453+        text = f.widget._format_value(result)
454+        self.assertEqual(text, "21.12.2010")
455+
456+    def test_localized_dateField_with_inputformat(self):
457+        "Localized DateFields with manually specified input formats can accept those formats"
458+        f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"], localize=True)
459+        # Parse a date in an unaccepted format; get an error
460+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
461+        self.assertRaises(forms.ValidationError, f.clean, '21/12/2010')
462+        self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
463+
464+        # Parse a date in a valid format, get a parsed result
465+        result = f.clean('12.21.2010')
466+        self.assertEqual(result, date(2010,12,21))
467+
468+        # # Check that the parsed result does a round trip to the same format
469+        text = f.widget._format_value(result)
470+        self.assertEqual(text, "21.12.2010")
471+
472+        # Parse a date in a valid format, get a parsed result
473+        result = f.clean('12-21-2010')
474+        self.assertEqual(result, date(2010,12,21))
475+
476+        # Check that the parsed result does a round trip to default format
477+        text = f.widget._format_value(result)
478+        self.assertEqual(text, "21.12.2010")
479+
480+class CustomDateInputFormatsTests(TestCase):
481+    def setUp(self):
482+        self.old_DATE_INPUT_FORMATS = settings.DATE_INPUT_FORMATS
483+        settings.DATE_INPUT_FORMATS = ["%d.%m.%Y", "%d-%m-%Y"]
484+
485+    def tearDown(self):
486+        settings.DATE_INPUT_FORMATS = self.old_DATE_INPUT_FORMATS
487+
488+    def test_dateField(self):
489+        "DateFields can parse dates in the default format"
490+        f = forms.DateField()
491+        # Parse a date in an unaccepted format; get an error
492+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
493+
494+        # Parse a date in a valid format, get a parsed result
495+        result = f.clean('21.12.2010')
496+        self.assertEqual(result, date(2010,12,21))
497+
498+        # Check that the parsed result does a round trip
499+        text = f.widget._format_value(result)
500+        self.assertEqual(text, '21.12.2010')
501+
502+        # Parse a date in a valid, but non-default format, get a parsed result
503+        result = f.clean('21-12-2010')
504+        self.assertEqual(result, date(2010,12,21))
505+
506+        # Check that the parsed result does a round trip to default format
507+        text = f.widget._format_value(result)
508+        self.assertEqual(text, "21.12.2010")
509+
510+    def test_localized_dateField(self):
511+        "Localized DateFields act as unlocalized widgets"
512+        f = forms.DateField(localize=True)
513+        # Parse a date in an unaccepted format; get an error
514+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
515+
516+        # Parse a date in a valid format, get a parsed result
517+        result = f.clean('21.12.2010')
518+        self.assertEqual(result, date(2010,12,21))
519+
520+        # Check that the parsed result does a round trip to the same format
521+        text = f.widget._format_value(result)
522+        self.assertEqual(text, '21.12.2010')
523+
524+        # Parse a date in a valid format, get a parsed result
525+        result = f.clean('21-12-2010')
526+        self.assertEqual(result, date(2010,12,21))
527+
528+        # Check that the parsed result does a round trip to default format
529+        text = f.widget._format_value(result)
530+        self.assertEqual(text, "21.12.2010")
531+
532+    def test_dateField_with_inputformat(self):
533+        "DateFields with manually specified input formats can accept those formats"
534+        f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"])
535+        # Parse a date in an unaccepted format; get an error
536+        self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
537+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
538+
539+        # Parse a date in a valid format, get a parsed result
540+        result = f.clean('12.21.2010')
541+        self.assertEqual(result, date(2010,12,21))
542+
543+        # Check that the parsed result does a round trip to the same format
544+        text = f.widget._format_value(result)
545+        self.assertEqual(text, "21.12.2010")
546+
547+        # Parse a date in a valid format, get a parsed result
548+        result = f.clean('12-21-2010')
549+        self.assertEqual(result, date(2010,12,21))
550+
551+        # Check that the parsed result does a round trip to default format
552+        text = f.widget._format_value(result)
553+        self.assertEqual(text, "21.12.2010")
554+
555+    def test_localized_dateField_with_inputformat(self):
556+        "Localized DateFields with manually specified input formats can accept those formats"
557+        f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"], localize=True)
558+        # Parse a date in an unaccepted format; get an error
559+        self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
560+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
561+
562+        # Parse a date in a valid format, get a parsed result
563+        result = f.clean('12.21.2010')
564+        self.assertEqual(result, date(2010,12,21))
565+
566+        # # Check that the parsed result does a round trip to the same format
567+        text = f.widget._format_value(result)
568+        self.assertEqual(text, "21.12.2010")
569+
570+        # Parse a date in a valid format, get a parsed result
571+        result = f.clean('12-21-2010')
572+        self.assertEqual(result, date(2010,12,21))
573+
574+        # Check that the parsed result does a round trip to default format
575+        text = f.widget._format_value(result)
576+        self.assertEqual(text, "21.12.2010")
577+
578+class SimpleDateFormatTests(TestCase):
579+    def test_dateField(self):
580+        "DateFields can parse dates in the default format"
581+        f = forms.DateField()
582+        # Parse a date in an unaccepted format; get an error
583+        self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
584+
585+        # Parse a date in a valid format, get a parsed result
586+        result = f.clean('2010-12-21')
587+        self.assertEqual(result, date(2010,12,21))
588+
589+        # Check that the parsed result does a round trip to the same format
590+        text = f.widget._format_value(result)
591+        self.assertEqual(text, "2010-12-21")
592+
593+        # Parse a date in a valid, but non-default format, get a parsed result
594+        result = f.clean('12/21/2010')
595+        self.assertEqual(result, date(2010,12,21))
596+
597+        # Check that the parsed result does a round trip to default format
598+        text = f.widget._format_value(result)
599+        self.assertEqual(text, "2010-12-21")
600+
601+    def test_localized_dateField(self):
602+        "Localized DateFields in a non-localized environment act as unlocalized widgets"
603+        f = forms.DateField()
604+        # Parse a date in an unaccepted format; get an error
605+        self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
606+
607+        # Parse a date in a valid format, get a parsed result
608+        result = f.clean('2010-12-21')
609+        self.assertEqual(result, date(2010,12,21))
610+
611+        # Check that the parsed result does a round trip to the same format
612+        text = f.widget._format_value(result)
613+        self.assertEqual(text, "2010-12-21")
614+
615+        # Parse a date in a valid format, get a parsed result
616+        result = f.clean('12/21/2010')
617+        self.assertEqual(result, date(2010,12,21))
618+
619+        # Check that the parsed result does a round trip to default format
620+        text = f.widget._format_value(result)
621+        self.assertEqual(text, "2010-12-21")
622+
623+    def test_dateField_with_inputformat(self):
624+        "DateFields with manually specified input formats can accept those formats"
625+        f = forms.DateField(input_formats=["%d.%m.%Y", "%d-%m-%Y"])
626+        # Parse a date in an unaccepted format; get an error
627+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
628+
629+        # Parse a date in a valid format, get a parsed result
630+        result = f.clean('21.12.2010')
631+        self.assertEqual(result, date(2010,12,21))
632+
633+        # Check that the parsed result does a round trip to the same format
634+        text = f.widget._format_value(result)
635+        self.assertEqual(text, "2010-12-21")
636+
637+        # Parse a date in a valid format, get a parsed result
638+        result = f.clean('21-12-2010')
639+        self.assertEqual(result, date(2010,12,21))
640+
641+        # Check that the parsed result does a round trip to default format
642+        text = f.widget._format_value(result)
643+        self.assertEqual(text, "2010-12-21")
644+
645+    def test_localized_dateField_with_inputformat(self):
646+        "Localized DateFields with manually specified input formats can accept those formats"
647+        f = forms.DateField(input_formats=["%d.%m.%Y", "%d-%m-%Y"], localize=True)
648+        # Parse a date in an unaccepted format; get an error
649+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
650+
651+        # Parse a date in a valid format, get a parsed result
652+        result = f.clean('21.12.2010')
653+        self.assertEqual(result, date(2010,12,21))
654+
655+        # Check that the parsed result does a round trip to the same format
656+        text = f.widget._format_value(result)
657+        self.assertEqual(text, "2010-12-21")
658+
659+        # Parse a date in a valid format, get a parsed result
660+        result = f.clean('21-12-2010')
661+        self.assertEqual(result, date(2010,12,21))
662+
663+        # Check that the parsed result does a round trip to default format
664+        text = f.widget._format_value(result)
665+        self.assertEqual(text, "2010-12-21")
666+
667+class LocalizedDateTimeTests(TestCase):
668+    def setUp(self):
669+        self.old_DATETIME_INPUT_FORMATS = settings.DATETIME_INPUT_FORMATS
670+        self.old_USE_L10N = settings.USE_L10N
671+
672+        settings.DATETIME_INPUT_FORMATS = ["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"]
673+        settings.USE_L10N = True
674+
675+        activate('de')
676+
677+    def tearDown(self):
678+        settings.DATETIME_INPUT_FORMATS = self.old_DATETIME_INPUT_FORMATS
679+        settings.USE_L10N = self.old_USE_L10N
680+
681+        deactivate()
682+
683+    def test_dateTimeField(self):
684+        "DateTimeFields can parse dates in the default format"
685+        f = forms.DateTimeField()
686+        # Parse a date in an unaccepted format; get an error
687+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010')
688+
689+        # Parse a date in a valid format, get a parsed result
690+        result = f.clean('21.12.2010 13:30:05')
691+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
692+
693+        # Check that the parsed result does a round trip
694+        text = f.widget._format_value(result)
695+        self.assertEqual(text, '21.12.2010 13:30:05')
696+
697+        # Parse a date in a valid, but non-default format, get a parsed result
698+        result = f.clean('21.12.2010 13:30')
699+        self.assertEqual(result, datetime(2010,12,21,13,30))
700+
701+        # Check that the parsed result does a round trip to default format
702+        text = f.widget._format_value(result)
703+        self.assertEqual(text, "21.12.2010 13:30:00")
704+
705+    def test_localized_dateTimeField(self):
706+        "Localized DateTimeFields act as unlocalized widgets"
707+        f = forms.DateTimeField(localize=True)
708+        # Parse a date in an unaccepted format; get an error
709+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010')
710+
711+        # Parse a date in a valid format, get a parsed result
712+        result = f.clean('21.12.2010 13:30:05')
713+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
714+
715+        # Check that the parsed result does a round trip to the same format
716+        text = f.widget._format_value(result)
717+        self.assertEqual(text, '21.12.2010 13:30:05')
718+
719+        # Parse a date in a valid format, get a parsed result
720+        result = f.clean('21.12.2010 13:30')
721+        self.assertEqual(result, datetime(2010,12,21,13,30))
722+
723+        # Check that the parsed result does a round trip to default format
724+        text = f.widget._format_value(result)
725+        self.assertEqual(text, "21.12.2010 13:30:00")
726+
727+    def test_dateTimeField_with_inputformat(self):
728+        "DateTimeFields with manually specified input formats can accept those formats"
729+        f = forms.DateTimeField(input_formats=["%H.%M.%S %m.%d.%Y", "%H.%M %m-%d-%Y"])
730+        # Parse a date in an unaccepted format; get an error
731+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05 13:30:05')
732+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010')
733+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
734+
735+        # Parse a date in a valid format, get a parsed result
736+        result = f.clean('13.30.05 12.21.2010')
737+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
738+
739+        # Check that the parsed result does a round trip to the same format
740+        text = f.widget._format_value(result)
741+        self.assertEqual(text, "21.12.2010 13:30:05")
742+
743+        # Parse a date in a valid format, get a parsed result
744+        result = f.clean('13.30 12-21-2010')
745+        self.assertEqual(result, datetime(2010,12,21,13,30))
746+
747+        # Check that the parsed result does a round trip to default format
748+        text = f.widget._format_value(result)
749+        self.assertEqual(text, "21.12.2010 13:30:00")
750+
751+    def test_localized_dateTimeField_with_inputformat(self):
752+        "Localized DateTimeFields with manually specified input formats can accept those formats"
753+        f = forms.DateTimeField(input_formats=["%H.%M.%S %m.%d.%Y", "%H.%M %m-%d-%Y"], localize=True)
754+        # Parse a date in an unaccepted format; get an error
755+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
756+        self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010')
757+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
758+
759+        # Parse a date in a valid format, get a parsed result
760+        result = f.clean('13.30.05 12.21.2010')
761+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
762+
763+        # # Check that the parsed result does a round trip to the same format
764+        text = f.widget._format_value(result)
765+        self.assertEqual(text, "21.12.2010 13:30:05")
766+
767+        # Parse a date in a valid format, get a parsed result
768+        result = f.clean('13.30 12-21-2010')
769+        self.assertEqual(result, datetime(2010,12,21,13,30))
770+
771+        # Check that the parsed result does a round trip to default format
772+        text = f.widget._format_value(result)
773+        self.assertEqual(text, "21.12.2010 13:30:00")
774+
775+
776+class CustomDateTimeInputFormatsTests(TestCase):
777+    def setUp(self):
778+        self.old_DATETIME_INPUT_FORMATS = settings.DATETIME_INPUT_FORMATS
779+        settings.DATETIME_INPUT_FORMATS = ["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"]
780+
781+    def tearDown(self):
782+        settings.DATETIME_INPUT_FORMATS = self.old_DATETIME_INPUT_FORMATS
783+
784+    def test_dateTimeField(self):
785+        "DateTimeFields can parse dates in the default format"
786+        f = forms.DateTimeField()
787+        # Parse a date in an unaccepted format; get an error
788+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
789+
790+        # Parse a date in a valid format, get a parsed result
791+        result = f.clean('1:30:05 PM 21/12/2010')
792+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
793+
794+        # Check that the parsed result does a round trip
795+        text = f.widget._format_value(result)
796+        self.assertEqual(text, '01:30:05 PM 21/12/2010')
797+
798+        # Parse a date in a valid, but non-default format, get a parsed result
799+        result = f.clean('1:30 PM 21-12-2010')
800+        self.assertEqual(result, datetime(2010,12,21,13,30))
801+
802+        # Check that the parsed result does a round trip to default format
803+        text = f.widget._format_value(result)
804+        self.assertEqual(text, "01:30:00 PM 21/12/2010")
805+
806+    def test_localized_dateTimeField(self):
807+        "Localized DateTimeFields act as unlocalized widgets"
808+        f = forms.DateTimeField(localize=True)
809+        # Parse a date in an unaccepted format; get an error
810+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
811+
812+        # Parse a date in a valid format, get a parsed result
813+        result = f.clean('1:30:05 PM 21/12/2010')
814+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
815+
816+        # Check that the parsed result does a round trip to the same format
817+        text = f.widget._format_value(result)
818+        self.assertEqual(text, '01:30:05 PM 21/12/2010')
819+
820+        # Parse a date in a valid format, get a parsed result
821+        result = f.clean('1:30 PM 21-12-2010')
822+        self.assertEqual(result, datetime(2010,12,21,13,30))
823+
824+        # Check that the parsed result does a round trip to default format
825+        text = f.widget._format_value(result)
826+        self.assertEqual(text, "01:30:00 PM 21/12/2010")
827+
828+    def test_dateTimeField_with_inputformat(self):
829+        "DateTimeFields with manually specified input formats can accept those formats"
830+        f = forms.DateTimeField(input_formats=["%m.%d.%Y %H:%M:%S", "%m-%d-%Y %H:%M"])
831+        # Parse a date in an unaccepted format; get an error
832+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
833+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
834+
835+        # Parse a date in a valid format, get a parsed result
836+        result = f.clean('12.21.2010 13:30:05')
837+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
838+
839+        # Check that the parsed result does a round trip to the same format
840+        text = f.widget._format_value(result)
841+        self.assertEqual(text, "01:30:05 PM 21/12/2010")
842+
843+        # Parse a date in a valid format, get a parsed result
844+        result = f.clean('12-21-2010 13:30')
845+        self.assertEqual(result, datetime(2010,12,21,13,30))
846+
847+        # Check that the parsed result does a round trip to default format
848+        text = f.widget._format_value(result)
849+        self.assertEqual(text, "01:30:00 PM 21/12/2010")
850+
851+    def test_localized_dateTimeField_with_inputformat(self):
852+        "Localized DateTimeFields with manually specified input formats can accept those formats"
853+        f = forms.DateTimeField(input_formats=["%m.%d.%Y %H:%M:%S", "%m-%d-%Y %H:%M"], localize=True)
854+        # Parse a date in an unaccepted format; get an error
855+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
856+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
857+
858+        # Parse a date in a valid format, get a parsed result
859+        result = f.clean('12.21.2010 13:30:05')
860+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
861+
862+        # # Check that the parsed result does a round trip to the same format
863+        text = f.widget._format_value(result)
864+        self.assertEqual(text, "01:30:05 PM 21/12/2010")
865+
866+        # Parse a date in a valid format, get a parsed result
867+        result = f.clean('12-21-2010 13:30')
868+        self.assertEqual(result, datetime(2010,12,21,13,30))
869+
870+        # Check that the parsed result does a round trip to default format
871+        text = f.widget._format_value(result)
872+        self.assertEqual(text, "01:30:00 PM 21/12/2010")
873+
874+class SimpleDateTimeFormatTests(TestCase):
875+    def test_dateTimeField(self):
876+        "DateTimeFields can parse dates in the default format"
877+        f = forms.DateTimeField()
878+        # Parse a date in an unaccepted format; get an error
879+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
880+
881+        # Parse a date in a valid format, get a parsed result
882+        result = f.clean('2010-12-21 13:30:05')
883+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
884+
885+        # Check that the parsed result does a round trip to the same format
886+        text = f.widget._format_value(result)
887+        self.assertEqual(text, "2010-12-21 13:30:05")
888+
889+        # Parse a date in a valid, but non-default format, get a parsed result
890+        result = f.clean('12/21/2010 13:30:05')
891+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
892+
893+        # Check that the parsed result does a round trip to default format
894+        text = f.widget._format_value(result)
895+        self.assertEqual(text, "2010-12-21 13:30:05")
896+
897+    def test_localized_dateTimeField(self):
898+        "Localized DateTimeFields in a non-localized environment act as unlocalized widgets"
899+        f = forms.DateTimeField()
900+        # Parse a date in an unaccepted format; get an error
901+        self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
902+
903+        # Parse a date in a valid format, get a parsed result
904+        result = f.clean('2010-12-21 13:30:05')
905+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
906+
907+        # Check that the parsed result does a round trip to the same format
908+        text = f.widget._format_value(result)
909+        self.assertEqual(text, "2010-12-21 13:30:05")
910+
911+        # Parse a date in a valid format, get a parsed result
912+        result = f.clean('12/21/2010 13:30:05')
913+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
914+
915+        # Check that the parsed result does a round trip to default format
916+        text = f.widget._format_value(result)
917+        self.assertEqual(text, "2010-12-21 13:30:05")
918+
919+    def test_dateTimeField_with_inputformat(self):
920+        "DateTimeFields with manually specified input formats can accept those formats"
921+        f = forms.DateTimeField(input_formats=["%I:%M:%S %p %d.%m.%Y", "%I:%M %p %d-%m-%Y"])
922+        # Parse a date in an unaccepted format; get an error
923+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
924+
925+        # Parse a date in a valid format, get a parsed result
926+        result = f.clean('1:30:05 PM 21.12.2010')
927+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
928+
929+        # Check that the parsed result does a round trip to the same format
930+        text = f.widget._format_value(result)
931+        self.assertEqual(text, "2010-12-21 13:30:05")
932+
933+        # Parse a date in a valid format, get a parsed result
934+        result = f.clean('1:30 PM 21-12-2010')
935+        self.assertEqual(result, datetime(2010,12,21,13,30))
936+
937+        # Check that the parsed result does a round trip to default format
938+        text = f.widget._format_value(result)
939+        self.assertEqual(text, "2010-12-21 13:30:00")
940+
941+    def test_localized_dateTimeField_with_inputformat(self):
942+        "Localized DateTimeFields with manually specified input formats can accept those formats"
943+        f = forms.DateTimeField(input_formats=["%I:%M:%S %p %d.%m.%Y", "%I:%M %p %d-%m-%Y"], localize=True)
944+        # Parse a date in an unaccepted format; get an error
945+        self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
946+
947+        # Parse a date in a valid format, get a parsed result
948+        result = f.clean('1:30:05 PM 21.12.2010')
949+        self.assertEqual(result, datetime(2010,12,21,13,30,5))
950+
951+        # Check that the parsed result does a round trip to the same format
952+        text = f.widget._format_value(result)
953+        self.assertEqual(text, "2010-12-21 13:30:05")
954+
955+        # Parse a date in a valid format, get a parsed result
956+        result = f.clean('1:30 PM 21-12-2010')
957+        self.assertEqual(result, datetime(2010,12,21,13,30))
958+
959+        # Check that the parsed result does a round trip to default format
960+        text = f.widget._format_value(result)
961+        self.assertEqual(text, "2010-12-21 13:30:00")
962diff -r b2f7c125865a tests/regressiontests/forms/tests.py
963--- a/tests/regressiontests/forms/tests.py      Fri Jul 30 04:15:16 2010 +0000
964+++ b/tests/regressiontests/forms/tests.py      Wed Aug 04 15:29:56 2010 +0800
965@@ -41,6 +41,8 @@
966 from validators import TestFieldWithValidators
967 from widgets import WidgetTests
968 
969+from input_formats import *
970+
971 __test__ = {
972     'extra_tests': extra_tests,
973     'form_tests': form_tests,