diff -r 4e639b179fc5 django/contrib/admin/widgets.py
a
|
b
|
|
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 -r 4e639b179fc5 django/forms/fields.py
a
|
b
|
|
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) |
… |
… |
|
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 | |
… |
… |
|
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 -r 4e639b179fc5 django/forms/forms.py
a
|
b
|
|
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 -r 4e639b179fc5 django/forms/widgets.py
a
|
b
|
|
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 |
… |
… |
|
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: |
… |
… |
|
208 | 209 | """ |
209 | 210 | input_type = None # Subclasses must define this. |
210 | 211 | |
| 212 | def _format_value(self, value): |
| 213 | if self.is_localized: |
| 214 | return formats.localize_input(value) |
| 215 | return value |
| 216 | |
211 | 217 | def render(self, name, value, attrs=None): |
212 | | if value is None: value = '' |
| 218 | if value is None: |
| 219 | value = '' |
213 | 220 | final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) |
214 | 221 | if value != '': |
215 | 222 | # Only add the 'value' attribute if a value is non-empty. |
216 | | final_attrs['value'] = force_unicode(value) |
| 223 | final_attrs['value'] = force_unicode(self._format_value(value)) |
217 | 224 | return mark_safe(u'<input%s />' % flatatt(final_attrs)) |
218 | 225 | |
219 | 226 | class TextInput(Input): |
… |
… |
|
295 | 302 | |
296 | 303 | class DateInput(Input): |
297 | 304 | input_type = 'text' |
298 | | format = None |
| 305 | format = '%Y-%m-%d' # '2006-10-25' |
299 | 306 | |
300 | 307 | def __init__(self, attrs=None, format=None): |
301 | 308 | super(DateInput, self).__init__(attrs) |
… |
… |
|
303 | 310 | self.format = format |
304 | 311 | |
305 | 312 | def _format_value(self, value): |
306 | | if value is None: |
307 | | return '' |
| 313 | if self.is_localized: |
| 314 | return formats.localize_input(value) |
308 | 315 | elif hasattr(value, 'strftime'): |
309 | | return formats.localize_input(value, self.format) |
| 316 | value = datetime_safe.new_date(value) |
| 317 | return value.strftime(self.format) |
310 | 318 | return value |
311 | 319 | |
312 | | def render(self, name, value, attrs=None): |
313 | | value = self._format_value(value) |
314 | | return super(DateInput, self).render(name, value, attrs) |
315 | | |
316 | 320 | def _has_changed(self, initial, data): |
317 | 321 | # If our field has show_hidden_initial=True, initial will be a string |
318 | 322 | # formatted by HiddenInput using formats.localize_input, which is not |
… |
… |
|
326 | 330 | |
327 | 331 | class DateTimeInput(Input): |
328 | 332 | input_type = 'text' |
329 | | format = None |
| 333 | format = '%Y-%m-%d %H:%M:%S' # '2006-10-25 14:30:59' |
330 | 334 | |
331 | 335 | def __init__(self, attrs=None, format=None): |
332 | 336 | super(DateTimeInput, self).__init__(attrs) |
… |
… |
|
334 | 338 | self.format = format |
335 | 339 | |
336 | 340 | def _format_value(self, value): |
337 | | if value is None: |
338 | | return '' |
| 341 | if self.is_localized: |
| 342 | return formats.localize_input(value) |
339 | 343 | elif hasattr(value, 'strftime'): |
340 | | return formats.localize_input(value, self.format) |
| 344 | value = datetime_safe.new_datetime(value) |
| 345 | return value.strftime(self.format) |
341 | 346 | return value |
342 | 347 | |
343 | | def render(self, name, value, attrs=None): |
344 | | value = self._format_value(value) |
345 | | return super(DateTimeInput, self).render(name, value, attrs) |
346 | | |
347 | 348 | def _has_changed(self, initial, data): |
348 | 349 | # If our field has show_hidden_initial=True, initial will be a string |
349 | 350 | # formatted by HiddenInput using formats.localize_input, which is not |
… |
… |
|
357 | 358 | |
358 | 359 | class TimeInput(Input): |
359 | 360 | input_type = 'text' |
360 | | format = None |
| 361 | format = '%H:%M:%S' # '14:30:59' |
361 | 362 | |
362 | 363 | def __init__(self, attrs=None, format=None): |
363 | 364 | super(TimeInput, self).__init__(attrs) |
… |
… |
|
365 | 366 | self.format = format |
366 | 367 | |
367 | 368 | def _format_value(self, value): |
368 | | if value is None: |
369 | | return '' |
| 369 | if self.is_localized: |
| 370 | return formats.localize_input(value) |
370 | 371 | elif hasattr(value, 'strftime'): |
371 | | return formats.localize_input(value, self.format) |
| 372 | return value.strftime(self.format) |
372 | 373 | return value |
373 | 374 | |
374 | | def render(self, name, value, attrs=None): |
375 | | value = self._format_value(value) |
376 | | return super(TimeInput, self).render(name, value, attrs) |
377 | | |
378 | 375 | def _has_changed(self, initial, data): |
379 | 376 | # If our field has show_hidden_initial=True, initial will be a string |
380 | 377 | # formatted by HiddenInput using formats.localize_input, which is not |
… |
… |
|
674 | 671 | super(MultiWidget, self).__init__(attrs) |
675 | 672 | |
676 | 673 | def render(self, name, value, attrs=None): |
| 674 | if self.is_localized: |
| 675 | for widget in self.widgets: |
| 676 | widget.is_localized = self.is_localized |
677 | 677 | # value is a list of values, each corresponding to a widget |
678 | 678 | # in self.widgets. |
679 | 679 | if not isinstance(value, list): |
diff -r 4e639b179fc5 tests/regressiontests/admin_widgets/models.py
a
|
b
|
|
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 -r 4e639b179fc5 tests/regressiontests/forms/widgets.py
a
|
b
|
|
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() |
… |
… |
|
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() |
… |
… |
|
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() |
… |
… |
|
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 -r 4e639b179fc5 tests/regressiontests/i18n/forms.py
a
|
b
|
|
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 |