summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJannis Leidel <jannis@leidel.info>2010-05-21 14:07:54 +0000
committerJannis Leidel <jannis@leidel.info>2010-05-21 14:07:54 +0000
commitb057a8b247d14328f058b8bc89da0519516ced82 (patch)
tree800a8fbb2790d22c1c96b5570f81c847db197e52
parent8a6cb3d969b6fd18abb952b8d0e5ccd10488a742 (diff)
downloaddjango-b057a8b247d14328f058b8bc89da0519516ced82.tar.gz
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
-rw-r--r--django/contrib/admin/widgets.py2
-rw-r--r--django/forms/fields.py14
-rw-r--r--django/forms/forms.py2
-rw-r--r--django/forms/widgets.py54
-rw-r--r--tests/regressiontests/admin_widgets/models.py1
-rw-r--r--tests/regressiontests/forms/widgets.py4
-rw-r--r--tests/regressiontests/i18n/forms.py1
7 files changed, 43 insertions, 35 deletions
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index d10c9c11ee..1d321d0620 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -44,7 +44,7 @@ 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.DateTimeInput):
+class AdminDateWidget(forms.DateInput):
class Media:
js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js",
settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js")
diff --git a/django/forms/fields.py b/django/forms/fields.py
index 14152c81a0..0bae4ba157 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -105,6 +105,8 @@ class Field(object):
# 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 @@ class Field(object):
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 @@ class SplitDateTimeField(MultiValueField):
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)
diff --git a/django/forms/forms.py b/django/forms/forms.py
index 6076065b59..b3718efa9a 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -443,8 +443,6 @@ class BoundField(StrAndUnicode):
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):
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 73d0f89222..e3799c69ad 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -10,7 +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 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 @@ class Textarea(Widget):
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 @@ class DateInput(Input):
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 @@ class DateInput(Input):
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 @@ class DateTimeInput(Input):
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 @@ class DateTimeInput(Input):
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 @@ class TimeInput(Input):
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 @@ class MultiWidget(Widget):
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):
diff --git a/tests/regressiontests/admin_widgets/models.py b/tests/regressiontests/admin_widgets/models.py
index 5632548414..59d625ba12 100644
--- a/tests/regressiontests/admin_widgets/models.py
+++ b/tests/regressiontests/admin_widgets/models.py
@@ -105,6 +105,7 @@ HTML escaped.
<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()
diff --git a/tests/regressiontests/forms/widgets.py b/tests/regressiontests/forms/widgets.py
index 0b2ccebbb1..39d7d569a3 100644
--- a/tests/regressiontests/forms/widgets.py
+++ b/tests/regressiontests/forms/widgets.py
@@ -1135,6 +1135,7 @@ u'<input type="text" name="date" value="2007-09-17 12:51:34" />'
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 @@ u'<input type="text" name="date" value="2007-09-17" />'
>>> 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 @@ u'<input type="text" name="time" value="13:12:11" />'
>>> 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" n
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()
diff --git a/tests/regressiontests/i18n/forms.py b/tests/regressiontests/i18n/forms.py
index 216d1fec01..156441c6ab 100644
--- a/tests/regressiontests/i18n/forms.py
+++ b/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