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 |