diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 0392b642bb..120df94cf3 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -41,21 +41,21 @@ class FilteredSelectMultiple(forms.SelectMultiple): (name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), settings.ADMIN_MEDIA_PREFIX)) return mark_safe(u''.join(output)) -class AdminDateWidget(forms.TextInput): +class AdminDateWidget(forms.DateTimeInput): class Media: js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js") - def __init__(self, attrs={}): - super(AdminDateWidget, self).__init__(attrs={'class': 'vDateField', 'size': '10'}) + def __init__(self, attrs={}, format=None): + super(AdminDateWidget, self).__init__(attrs={'class': 'vDateField', 'size': '10'}, format=format) -class AdminTimeWidget(forms.TextInput): +class AdminTimeWidget(forms.TimeInput): class Media: js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js") - def __init__(self, attrs={}): - super(AdminTimeWidget, self).__init__(attrs={'class': 'vTimeField', 'size': '8'}) + def __init__(self, attrs={}, format=None): + super(AdminTimeWidget, self).__init__(attrs={'class': 'vTimeField', 'size': '8'}, format=format) class AdminSplitDateTime(forms.SplitDateTimeWidget): """ diff --git a/django/forms/widgets.py b/django/forms/widgets.py index aabd1b017d..c16c239de1 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -10,8 +10,7 @@ from django.utils.html import escape, conditional_escape from django.utils.translation import ugettext from django.utils.encoding import StrAndUnicode, force_unicode from django.utils.safestring import mark_safe -from django.utils.formats import localize -from django.utils import datetime_safe +from django.utils import datetime_safe, formats from datetime import time from util import flatatt from urlparse import urljoin @@ -209,7 +208,7 @@ class Input(Widget): final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) if value != '': # Only add the 'value' attribute if a value is non-empty. - final_attrs['value'] = force_unicode(localize(value, is_input=True)) + final_attrs['value'] = force_unicode(formats.localize_input(value)) return mark_safe(u'' % flatatt(final_attrs)) class TextInput(Input): @@ -284,7 +283,7 @@ class Textarea(Widget): class DateInput(Input): input_type = 'text' - format = '%Y-%m-%d' # '2006-10-25' + format = None def __init__(self, attrs=None, format=None): super(DateInput, self).__init__(attrs) @@ -295,8 +294,7 @@ class DateInput(Input): if value is None: return '' elif hasattr(value, 'strftime'): - value = datetime_safe.new_date(value) - return value.strftime(self.format) + return formats.localize_input(value, self.format) return value def render(self, name, value, attrs=None): @@ -308,7 +306,7 @@ class DateInput(Input): class DateTimeInput(Input): input_type = 'text' - format = '%Y-%m-%d %H:%M:%S' # '2006-10-25 14:30:59' + format = None def __init__(self, attrs=None, format=None): super(DateTimeInput, self).__init__(attrs) @@ -319,8 +317,7 @@ class DateTimeInput(Input): if value is None: return '' elif hasattr(value, 'strftime'): - value = datetime_safe.new_datetime(value) - return value.strftime(self.format) + return formats.localize_input(value, self.format) return value def render(self, name, value, attrs=None): @@ -332,7 +329,7 @@ class DateTimeInput(Input): class TimeInput(Input): input_type = 'text' - format = '%H:%M:%S' # '14:30:59' + format = None def __init__(self, attrs=None, format=None): super(TimeInput, self).__init__(attrs) @@ -343,7 +340,7 @@ class TimeInput(Input): if value is None: return '' elif hasattr(value, 'strftime'): - return value.strftime(self.format) + return formats.localize_input(value, self.format) return value def render(self, name, value, attrs=None): diff --git a/django/utils/formats.py b/django/utils/formats.py index e18e120b36..92e7e7f538 100644 --- a/django/utils/formats.py +++ b/django/utils/formats.py @@ -4,8 +4,8 @@ import datetime from django.conf import settings from django.utils.translation import get_language, to_locale, check_for_language from django.utils.importlib import import_module -from django.utils import dateformat -from django.utils import numberformat +from django.utils.encoding import smart_str +from django.utils import dateformat, numberformat, datetime_safe def get_format_modules(): """ @@ -65,11 +65,10 @@ def number_format(value, decimal_pos=None): get_format('THOUSAND_SEPARATOR'), ) -def localize(value, is_input=False): +def localize(value): """ - Checks value, and if it has a localizable type (date, - number...) it returns the value as a string using - current locale format + Checks if value is a localizable type (date, number...) and returns it + formatted as a string using current locale format """ if settings.USE_L10N: if isinstance(value, decimal.Decimal): @@ -79,19 +78,27 @@ def localize(value, is_input=False): elif isinstance(value, int): return number_format(value) elif isinstance(value, datetime.datetime): - if not is_input: - return date_format(value, 'DATETIME_FORMAT') - else: - return value.strftime(get_format('DATETIME_INPUT_FORMATS')[0]) + return date_format(value, 'DATETIME_FORMAT') elif isinstance(value, datetime.date): - if not is_input: - return date_format(value) - else: - return value.strftime(get_format('DATE_INPUT_FORMATS')[0]) + return date_format(value) elif isinstance(value, datetime.time): - if not is_input: - return date_format(value, 'TIME_FORMAT') - else: - return value.strftime(get_format('TIME_INPUT_FORMATS')[0]) + return date_format(value, 'TIME_FORMAT') return value +def localize_input(value, default=None): + """ + Checks if an input value is a localizable type and returns it + formatted with the appropriate formatting string of the current locale. + """ + if isinstance(value, datetime.datetime): + value = datetime_safe.new_datetime(value) + format = smart_str(default or get_format('DATETIME_INPUT_FORMATS')[0]) + return value.strftime(format) + elif isinstance(value, datetime.date): + value = datetime_safe.new_date(value) + format = smart_str(default or get_format('DATE_INPUT_FORMATS')[0]) + return value.strftime(format) + elif isinstance(value, datetime.time): + format = smart_str(default or get_format('TIME_INPUT_FORMATS')[0]) + return value.strftime(format) + return value diff --git a/tests/regressiontests/admin_widgets/models.py b/tests/regressiontests/admin_widgets/models.py index 0c81ed3119..b9fe67c182 100644 --- a/tests/regressiontests/admin_widgets/models.py +++ b/tests/regressiontests/admin_widgets/models.py @@ -77,6 +77,9 @@ __test__ = {'WIDGETS_TESTS': """ >>> from django.contrib.admin.widgets import FilteredSelectMultiple, AdminSplitDateTime >>> from django.contrib.admin.widgets import AdminFileWidget, ForeignKeyRawIdWidget, ManyToManyRawIdWidget >>> from django.contrib.admin.widgets import RelatedFieldWidgetWrapper +>>> from django.utils.translation import activate, deactivate +>>> from django.conf import settings + Calling conditional_escape on the output of widget.render will simulate what happens in the template. This is easier than setting up a template and context @@ -94,6 +97,12 @@ HTML escaped. >>> w = AdminSplitDateTime() >>> print conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30)))
Date:
Time:
Datum:
Zeit: