Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #13560 -- Fixed localization of widgets.

Particularly this fixes the SplitDateTimeField and the AdminDateWidget by localizating the widget's value in its render method instead of the form field. Thanks to David Danier for the report and Russell for help with the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13296 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit b057a8b247d14328f058b8bc89da0519516ced82 1 parent 8a6cb3d
@jezdez jezdez authored
View
2  django/contrib/admin/widgets.py
@@ -44,7 +44,7 @@ def render(self, name, value, attrs=None, choices=()):
(name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), settings.ADMIN_MEDIA_PREFIX))
return mark_safe(u''.join(output))
-class AdminDateWidget(forms.DateTimeInput):
+class AdminDateWidget(forms.DateInput):
class Media:
js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js",
settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js")
View
14 django/forms/fields.py
@@ -105,6 +105,8 @@ def __init__(self, required=True, widget=None, label=None, initial=None,
# Trigger the localization machinery if needed.
self.localize = localize
+ if self.localize:
+ widget.is_localized = True
# Hook into self.widget_attrs() for any Field-specific HTML attributes.
extra_attrs = self.widget_attrs(widget)
@@ -125,9 +127,6 @@ def __init__(self, required=True, widget=None, label=None, initial=None,
self.validators = self.default_validators + validators
- def localize_value(self, value):
- return formats.localize_input(value)
-
def to_python(self, value):
return value
@@ -843,9 +842,14 @@ def __init__(self, input_date_formats=None, input_time_formats=None, *args, **kw
errors = self.default_error_messages.copy()
if 'error_messages' in kwargs:
errors.update(kwargs['error_messages'])
+ localize = kwargs.get('localize', False)
fields = (
- DateField(input_formats=input_date_formats, error_messages={'invalid': errors['invalid_date']}),
- TimeField(input_formats=input_time_formats, error_messages={'invalid': errors['invalid_time']}),
+ DateField(input_formats=input_date_formats,
+ error_messages={'invalid': errors['invalid_date']},
+ localize=localize),
+ TimeField(input_formats=input_time_formats,
+ error_messages={'invalid': errors['invalid_time']},
+ localize=localize),
)
super(SplitDateTimeField, self).__init__(fields, *args, **kwargs)
View
2  django/forms/forms.py
@@ -443,8 +443,6 @@ def as_widget(self, widget=None, attrs=None, only_initial=False):
name = self.html_name
else:
name = self.html_initial_name
- if self.field.localize:
- data = self.field.localize_value(data)
return widget.render(name, data, attrs=attrs)
def as_text(self, attrs=None, **kwargs):
View
54 django/forms/widgets.py
@@ -10,7 +10,7 @@
from django.utils.translation import ugettext
from django.utils.encoding import StrAndUnicode, force_unicode
from django.utils.safestring import mark_safe
-from django.utils import formats
+from django.utils import datetime_safe, formats
import time
import datetime
from util import flatatt
@@ -133,6 +133,7 @@ class Widget(object):
__metaclass__ = MediaDefiningClass
is_hidden = False # Determines whether this corresponds to an <input type="hidden">.
needs_multipart_form = False # Determines does this widget need multipart-encrypted form
+ is_localized = False
def __init__(self, attrs=None):
if attrs is not None:
@@ -208,12 +209,18 @@ class Input(Widget):
"""
input_type = None # Subclasses must define this.
+ def _format_value(self, value):
+ if self.is_localized:
+ return formats.localize_input(value)
+ return value
+
def render(self, name, value, attrs=None):
- if value is None: value = ''
+ if value is None:
+ value = ''
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(value)
+ final_attrs['value'] = force_unicode(self._format_value(value))
return mark_safe(u'<input%s />' % flatatt(final_attrs))
class TextInput(Input):
@@ -295,7 +302,7 @@ def render(self, name, value, attrs=None):
class DateInput(Input):
input_type = 'text'
- format = None
+ format = '%Y-%m-%d' # '2006-10-25'
def __init__(self, attrs=None, format=None):
super(DateInput, self).__init__(attrs)
@@ -303,16 +310,13 @@ def __init__(self, attrs=None, format=None):
self.format = format
def _format_value(self, value):
- if value is None:
- return ''
+ if self.is_localized:
+ return formats.localize_input(value)
elif hasattr(value, 'strftime'):
- return formats.localize_input(value, self.format)
+ value = datetime_safe.new_date(value)
+ return value.strftime(self.format)
return value
- def render(self, name, value, attrs=None):
- value = self._format_value(value)
- return super(DateInput, self).render(name, value, attrs)
-
def _has_changed(self, initial, data):
# If our field has show_hidden_initial=True, initial will be a string
# formatted by HiddenInput using formats.localize_input, which is not
@@ -326,7 +330,7 @@ def _has_changed(self, initial, data):
class DateTimeInput(Input):
input_type = 'text'
- format = None
+ format = '%Y-%m-%d %H:%M:%S' # '2006-10-25 14:30:59'
def __init__(self, attrs=None, format=None):
super(DateTimeInput, self).__init__(attrs)
@@ -334,16 +338,13 @@ def __init__(self, attrs=None, format=None):
self.format = format
def _format_value(self, value):
- if value is None:
- return ''
+ if self.is_localized:
+ return formats.localize_input(value)
elif hasattr(value, 'strftime'):
- return formats.localize_input(value, self.format)
+ value = datetime_safe.new_datetime(value)
+ return value.strftime(self.format)
return value
- def render(self, name, value, attrs=None):
- value = self._format_value(value)
- return super(DateTimeInput, self).render(name, value, attrs)
-
def _has_changed(self, initial, data):
# If our field has show_hidden_initial=True, initial will be a string
# formatted by HiddenInput using formats.localize_input, which is not
@@ -357,7 +358,7 @@ def _has_changed(self, initial, data):
class TimeInput(Input):
input_type = 'text'
- format = None
+ format = '%H:%M:%S' # '14:30:59'
def __init__(self, attrs=None, format=None):
super(TimeInput, self).__init__(attrs)
@@ -365,16 +366,12 @@ def __init__(self, attrs=None, format=None):
self.format = format
def _format_value(self, value):
- if value is None:
- return ''
+ if self.is_localized:
+ return formats.localize_input(value)
elif hasattr(value, 'strftime'):
- return formats.localize_input(value, self.format)
+ return value.strftime(self.format)
return value
- def render(self, name, value, attrs=None):
- value = self._format_value(value)
- return super(TimeInput, self).render(name, value, attrs)
-
def _has_changed(self, initial, data):
# If our field has show_hidden_initial=True, initial will be a string
# formatted by HiddenInput using formats.localize_input, which is not
@@ -674,6 +671,9 @@ def __init__(self, widgets, attrs=None):
super(MultiWidget, self).__init__(attrs)
def render(self, name, value, attrs=None):
+ if self.is_localized:
+ for widget in self.widgets:
+ widget.is_localized = self.is_localized
# value is a list of values, each corresponding to a widget
# in self.widgets.
if not isinstance(value, list):
View
1  tests/regressiontests/admin_widgets/models.py
@@ -105,6 +105,7 @@ class CarTire(models.Model):
<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>
>>> activate('de-at')
>>> settings.USE_L10N = True
+>>> w.is_localized = True
>>> print conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30)))
<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>
>>> deactivate()
View
4 tests/regressiontests/forms/widgets.py
@@ -1135,6 +1135,7 @@
u'<input type="text" name="date" value="2007-09-17 12:51:00" />'
>>> activate('de-at')
>>> settings.USE_L10N = True
+>>> w.is_localized = True
>>> w.render('date', d)
u'<input type="text" name="date" value="17.09.2007 12:51:34" />'
>>> deactivate()
@@ -1176,6 +1177,7 @@
>>> activate('de-at')
>>> settings.USE_L10N = True
+>>> w.is_localized = True
>>> w.render('date', d)
u'<input type="text" name="date" value="17.09.2007" />'
>>> deactivate()
@@ -1220,6 +1222,7 @@
>>> activate('de-at')
>>> settings.USE_L10N = True
+>>> w.is_localized = True
>>> w.render('date', d)
u'<input type="text" name="date" value="17.09.2007" />'
>>> deactivate()
@@ -1259,6 +1262,7 @@
u'<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" name="date_1" value="12:51:00" />'
>>> activate('de-at')
>>> settings.USE_L10N = True
+>>> w.is_localized = True
>>> w.render('date', datetime.datetime(2007, 9, 17, 12, 51))
u'<input type="hidden" name="date_0" value="17.09.2007" /><input type="hidden" name="date_1" value="12:51:00" />'
>>> deactivate()
View
1  tests/regressiontests/i18n/forms.py
@@ -16,6 +16,7 @@ class SelectDateForm(forms.Form):
class CompanyForm(forms.ModelForm):
cents_payed = forms.DecimalField(max_digits=4, decimal_places=2, localize=True)
products_delivered = forms.IntegerField(localize=True)
+ date_added = forms.DateTimeField(localize=True)
class Meta:
model = Company
Please sign in to comment.
Something went wrong with that request. Please try again.