diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index d10c9c1..1d321d0 100644
a
|
b
|
class FilteredSelectMultiple(forms.SelectMultiple):
|
44 | 44 | (name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), settings.ADMIN_MEDIA_PREFIX)) |
45 | 45 | return mark_safe(u''.join(output)) |
46 | 46 | |
47 | | class AdminDateWidget(forms.DateTimeInput): |
| 47 | class AdminDateWidget(forms.DateInput): |
48 | 48 | class Media: |
49 | 49 | js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", |
50 | 50 | settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js") |
diff --git a/django/forms/fields.py b/django/forms/fields.py
index 14152c8..0bae4ba 100644
a
|
b
|
class Field(object):
|
105 | 105 | |
106 | 106 | # Trigger the localization machinery if needed. |
107 | 107 | self.localize = localize |
| 108 | if self.localize: |
| 109 | widget.is_localized = True |
108 | 110 | |
109 | 111 | # Hook into self.widget_attrs() for any Field-specific HTML attributes. |
110 | 112 | extra_attrs = self.widget_attrs(widget) |
… |
… |
class Field(object):
|
125 | 127 | |
126 | 128 | self.validators = self.default_validators + validators |
127 | 129 | |
128 | | def localize_value(self, value): |
129 | | return formats.localize_input(value) |
130 | | |
131 | 130 | def to_python(self, value): |
132 | 131 | return value |
133 | 132 | |
… |
… |
class SplitDateTimeField(MultiValueField):
|
843 | 842 | errors = self.default_error_messages.copy() |
844 | 843 | if 'error_messages' in kwargs: |
845 | 844 | errors.update(kwargs['error_messages']) |
| 845 | localize = kwargs.get('localize', False) |
846 | 846 | fields = ( |
847 | | DateField(input_formats=input_date_formats, error_messages={'invalid': errors['invalid_date']}), |
848 | | TimeField(input_formats=input_time_formats, error_messages={'invalid': errors['invalid_time']}), |
| 847 | DateField(input_formats=input_date_formats, |
| 848 | error_messages={'invalid': errors['invalid_date']}, |
| 849 | localize=localize), |
| 850 | TimeField(input_formats=input_time_formats, |
| 851 | error_messages={'invalid': errors['invalid_time']}, |
| 852 | localize=localize), |
849 | 853 | ) |
850 | 854 | super(SplitDateTimeField, self).__init__(fields, *args, **kwargs) |
851 | 855 | |
diff --git a/django/forms/forms.py b/django/forms/forms.py
index 6076065..b3718ef 100644
a
|
b
|
class BoundField(StrAndUnicode):
|
443 | 443 | name = self.html_name |
444 | 444 | else: |
445 | 445 | name = self.html_initial_name |
446 | | if self.field.localize: |
447 | | data = self.field.localize_value(data) |
448 | 446 | return widget.render(name, data, attrs=attrs) |
449 | 447 | |
450 | 448 | def as_text(self, attrs=None, **kwargs): |
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 73d0f89..a9b52aa 100644
a
|
b
|
from django.utils.html import escape, conditional_escape
|
10 | 10 | from django.utils.translation import ugettext |
11 | 11 | from django.utils.encoding import StrAndUnicode, force_unicode |
12 | 12 | from django.utils.safestring import mark_safe |
13 | | from django.utils import formats |
| 13 | from django.utils import datetime_safe, formats |
14 | 14 | import time |
15 | 15 | import datetime |
16 | 16 | from util import flatatt |
… |
… |
class Widget(object):
|
133 | 133 | __metaclass__ = MediaDefiningClass |
134 | 134 | is_hidden = False # Determines whether this corresponds to an <input type="hidden">. |
135 | 135 | needs_multipart_form = False # Determines does this widget need multipart-encrypted form |
| 136 | is_localized = False |
136 | 137 | |
137 | 138 | def __init__(self, attrs=None): |
138 | 139 | if attrs is not None: |
… |
… |
class Input(Widget):
|
209 | 210 | input_type = None # Subclasses must define this. |
210 | 211 | |
211 | 212 | def render(self, name, value, attrs=None): |
212 | | if value is None: value = '' |
| 213 | if value is None: |
| 214 | value = '' |
213 | 215 | final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) |
214 | 216 | if value != '': |
215 | 217 | # Only add the 'value' attribute if a value is non-empty. |
| 218 | if self.is_localized: |
| 219 | value = formats.localize_input(value) |
216 | 220 | final_attrs['value'] = force_unicode(value) |
217 | 221 | return mark_safe(u'<input%s />' % flatatt(final_attrs)) |
218 | 222 | |
… |
… |
class Textarea(Widget):
|
295 | 299 | |
296 | 300 | class DateInput(Input): |
297 | 301 | input_type = 'text' |
298 | | format = None |
| 302 | format = '%Y-%m-%d' # '2006-10-25' |
299 | 303 | |
300 | 304 | def __init__(self, attrs=None, format=None): |
301 | 305 | super(DateInput, self).__init__(attrs) |
… |
… |
class DateInput(Input):
|
305 | 309 | def _format_value(self, value): |
306 | 310 | if value is None: |
307 | 311 | return '' |
| 312 | elif self.is_localized: |
| 313 | return value |
308 | 314 | elif hasattr(value, 'strftime'): |
309 | | return formats.localize_input(value, self.format) |
| 315 | value = datetime_safe.new_date(value) |
| 316 | return value.strftime(self.format) |
310 | 317 | return value |
311 | 318 | |
312 | 319 | def render(self, name, value, attrs=None): |
… |
… |
class DateInput(Input):
|
326 | 333 | |
327 | 334 | class DateTimeInput(Input): |
328 | 335 | input_type = 'text' |
329 | | format = None |
| 336 | format = '%Y-%m-%d %H:%M:%S' # '2006-10-25 14:30:59' |
330 | 337 | |
331 | 338 | def __init__(self, attrs=None, format=None): |
332 | 339 | super(DateTimeInput, self).__init__(attrs) |
… |
… |
class DateTimeInput(Input):
|
336 | 343 | def _format_value(self, value): |
337 | 344 | if value is None: |
338 | 345 | return '' |
| 346 | elif self.is_localized: |
| 347 | return value |
339 | 348 | elif hasattr(value, 'strftime'): |
340 | | return formats.localize_input(value, self.format) |
| 349 | value = datetime_safe.new_datetime(value) |
| 350 | return value.strftime(self.format) |
341 | 351 | return value |
342 | 352 | |
343 | 353 | def render(self, name, value, attrs=None): |
… |
… |
class DateTimeInput(Input):
|
357 | 367 | |
358 | 368 | class TimeInput(Input): |
359 | 369 | input_type = 'text' |
360 | | format = None |
| 370 | format = '%H:%M:%S' # '14:30:59' |
361 | 371 | |
362 | 372 | def __init__(self, attrs=None, format=None): |
363 | 373 | super(TimeInput, self).__init__(attrs) |
… |
… |
class TimeInput(Input):
|
367 | 377 | def _format_value(self, value): |
368 | 378 | if value is None: |
369 | 379 | return '' |
| 380 | elif self.is_localized: |
| 381 | return value |
370 | 382 | elif hasattr(value, 'strftime'): |
371 | | return formats.localize_input(value, self.format) |
| 383 | return value.strftime(self.format) |
372 | 384 | return value |
373 | 385 | |
374 | 386 | def render(self, name, value, attrs=None): |
… |
… |
class MultiWidget(Widget):
|
674 | 686 | super(MultiWidget, self).__init__(attrs) |
675 | 687 | |
676 | 688 | def render(self, name, value, attrs=None): |
| 689 | if self.is_localized: |
| 690 | for widget in self.widgets: |
| 691 | widget.is_localized = self.is_localized |
677 | 692 | # value is a list of values, each corresponding to a widget |
678 | 693 | # in self.widgets. |
679 | 694 | if not isinstance(value, list): |
diff --git a/tests/regressiontests/admin_widgets/models.py b/tests/regressiontests/admin_widgets/models.py
index 5632548..59d625b 100644
a
|
b
|
HTML escaped.
|
105 | 105 | <p class="datetime">Date: <input value="2007-12-01" type="text" class="vDateField" name="test_0" size="10" /><br />Time: <input value="09:30:00" type="text" class="vTimeField" name="test_1" size="8" /></p> |
106 | 106 | >>> activate('de-at') |
107 | 107 | >>> settings.USE_L10N = True |
| 108 | >>> w.is_localized = True |
108 | 109 | >>> print conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30))) |
109 | 110 | <p class="datetime">Datum: <input value="01.12.2007" type="text" class="vDateField" name="test_0" size="10" /><br />Zeit: <input value="09:30:00" type="text" class="vTimeField" name="test_1" size="8" /></p> |
110 | 111 | >>> deactivate() |
diff --git a/tests/regressiontests/forms/widgets.py b/tests/regressiontests/forms/widgets.py
index 0b2cceb..39d7d56 100644
a
|
b
|
u'<input type="text" name="date" value="2007-09-17 12:51:34" />'
|
1135 | 1135 | u'<input type="text" name="date" value="2007-09-17 12:51:00" />' |
1136 | 1136 | >>> activate('de-at') |
1137 | 1137 | >>> settings.USE_L10N = True |
| 1138 | >>> w.is_localized = True |
1138 | 1139 | >>> w.render('date', d) |
1139 | 1140 | u'<input type="text" name="date" value="17.09.2007 12:51:34" />' |
1140 | 1141 | >>> deactivate() |
… |
… |
u'<input type="text" name="date" value="2007-09-17" />'
|
1176 | 1177 | |
1177 | 1178 | >>> activate('de-at') |
1178 | 1179 | >>> settings.USE_L10N = True |
| 1180 | >>> w.is_localized = True |
1179 | 1181 | >>> w.render('date', d) |
1180 | 1182 | u'<input type="text" name="date" value="17.09.2007" />' |
1181 | 1183 | >>> deactivate() |
… |
… |
u'<input type="text" name="time" value="13:12:11" />'
|
1220 | 1222 | |
1221 | 1223 | >>> activate('de-at') |
1222 | 1224 | >>> settings.USE_L10N = True |
| 1225 | >>> w.is_localized = True |
1223 | 1226 | >>> w.render('date', d) |
1224 | 1227 | u'<input type="text" name="date" value="17.09.2007" />' |
1225 | 1228 | >>> deactivate() |
… |
… |
u'<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" n
|
1259 | 1262 | u'<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" name="date_1" value="12:51:00" />' |
1260 | 1263 | >>> activate('de-at') |
1261 | 1264 | >>> settings.USE_L10N = True |
| 1265 | >>> w.is_localized = True |
1262 | 1266 | >>> w.render('date', datetime.datetime(2007, 9, 17, 12, 51)) |
1263 | 1267 | u'<input type="hidden" name="date_0" value="17.09.2007" /><input type="hidden" name="date_1" value="12:51:00" />' |
1264 | 1268 | >>> deactivate() |
diff --git a/tests/regressiontests/i18n/forms.py b/tests/regressiontests/i18n/forms.py
index 216d1fe..156441c 100644
a
|
b
|
class SelectDateForm(forms.Form):
|
16 | 16 | class CompanyForm(forms.ModelForm): |
17 | 17 | cents_payed = forms.DecimalField(max_digits=4, decimal_places=2, localize=True) |
18 | 18 | products_delivered = forms.IntegerField(localize=True) |
| 19 | date_added = forms.DateTimeField(localize=True) |
19 | 20 | |
20 | 21 | class Meta: |
21 | 22 | model = Company |