Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #13032 - Added localize parameter to form fields to be able to …

…selectively enable localization.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12867 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit ca4c6f65ea81109cf6fbdba74da7f5027eb0c4db 1 parent ad5afd6
@jezdez jezdez authored
View
20 django/forms/fields.py
@@ -71,7 +71,7 @@ class Field(object):
def __init__(self, required=True, widget=None, label=None, initial=None,
help_text=None, error_messages=None, show_hidden_initial=False,
- validators=[]):
+ validators=[], localize=False):
# required -- Boolean that specifies whether the field is required.
# True by default.
# widget -- A Widget class, or instance of a Widget class, that should
@@ -85,9 +85,12 @@ def __init__(self, required=True, widget=None, label=None, initial=None,
# initial -- A value to use in this Field's initial display. This value
# is *not* used as a fallback if data isn't given.
# help_text -- An optional string to use as "help text" for this Field.
+ # error_messages -- An optional dictionary to override the default
+ # messages that the field will raise.
# show_hidden_initial -- Boolean that specifies if it is needed to render a
# hidden widget with initial value after widget.
# validators -- List of addtional validators to use
+ # localize -- Boolean that specifies if the field should be localized.
if label is not None:
label = smart_unicode(label)
self.required, self.label, self.initial = required, label, initial
@@ -100,6 +103,9 @@ def __init__(self, required=True, widget=None, label=None, initial=None,
if isinstance(widget, type):
widget = widget()
+ # Trigger the localization machinery if needed.
+ self.localize = localize
+
# Hook into self.widget_attrs() for any Field-specific HTML attributes.
extra_attrs = self.widget_attrs(widget)
if extra_attrs:
@@ -119,6 +125,9 @@ 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
@@ -213,7 +222,8 @@ def to_python(self, value):
value = super(IntegerField, self).to_python(value)
if value in validators.EMPTY_VALUES:
return None
- value = formats.sanitize_separators(value)
+ if self.localize:
+ value = formats.sanitize_separators(value)
try:
value = int(str(value))
except (ValueError, TypeError):
@@ -233,7 +243,8 @@ def to_python(self, value):
value = super(IntegerField, self).to_python(value)
if value in validators.EMPTY_VALUES:
return None
- value = formats.sanitize_separators(value)
+ if self.localize:
+ value = formats.sanitize_separators(value)
try:
value = float(value)
except (ValueError, TypeError):
@@ -268,7 +279,8 @@ def to_python(self, value):
"""
if value in validators.EMPTY_VALUES:
return None
- value = formats.sanitize_separators(value)
+ if self.localize:
+ value = formats.sanitize_separators(value)
value = smart_str(value).strip()
try:
value = Decimal(value)
View
2  django/forms/forms.py
@@ -443,6 +443,8 @@ 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
17 django/forms/widgets.py
@@ -13,7 +13,6 @@
from django.utils import formats
import time
import datetime
-from django.utils.formats import get_format
from util import flatatt
from urlparse import urljoin
@@ -214,7 +213,7 @@ def render(self, name, value, attrs=None):
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(formats.localize_input(value))
+ final_attrs['value'] = force_unicode(value)
return mark_safe(u'<input%s />' % flatatt(final_attrs))
class TextInput(Input):
@@ -319,7 +318,7 @@ def _has_changed(self, initial, data):
# formatted by HiddenInput using formats.localize_input, which is not
# necessarily the format used for this widget. Attempt to convert it.
try:
- input_format = get_format('DATE_INPUT_FORMATS')[0]
+ input_format = formats.get_format('DATE_INPUT_FORMATS')[0]
initial = datetime.date(*time.strptime(initial, input_format)[:3])
except (TypeError, ValueError):
pass
@@ -350,7 +349,7 @@ def _has_changed(self, initial, data):
# formatted by HiddenInput using formats.localize_input, which is not
# necessarily the format used for this widget. Attempt to convert it.
try:
- input_format = get_format('DATETIME_INPUT_FORMATS')[0]
+ input_format = formats.get_format('DATETIME_INPUT_FORMATS')[0]
initial = datetime.datetime(*time.strptime(initial, input_format)[:6])
except (TypeError, ValueError):
pass
@@ -381,7 +380,7 @@ def _has_changed(self, initial, data):
# formatted by HiddenInput using formats.localize_input, which is not
# necessarily the format used for this widget. Attempt to convert it.
try:
- input_format = get_format('TIME_INPUT_FORMATS')[0]
+ input_format = formats.get_format('TIME_INPUT_FORMATS')[0]
initial = datetime.time(*time.strptime(initial, input_format)[3:6])
except (TypeError, ValueError):
pass
@@ -771,6 +770,8 @@ class SplitHiddenDateTimeWidget(SplitDateTimeWidget):
"""
is_hidden = True
- def __init__(self, attrs=None):
- widgets = (HiddenInput(attrs=attrs), HiddenInput(attrs=attrs))
- super(SplitDateTimeWidget, self).__init__(widgets, attrs)
+ def __init__(self, attrs=None, date_format=None, time_format=None):
+ super(SplitHiddenDateTimeWidget, self).__init__(attrs, date_format, time_format)
+ for widget in self.widgets:
+ widget.input_type = 'hidden'
+ widget.is_hidden = True
View
15 docs/ref/forms/fields.txt
@@ -259,6 +259,7 @@ error message keys it uses.
``validators``
~~~~~~~~~~~~~~
+
.. versionadded:: 1.2
.. attribute:: Field.validators
@@ -268,6 +269,20 @@ for this field.
See the :ref:`validators documentation <ref-validators>` for more information.
+``localize``
+~~~~~~~~~~~~
+
+.. versionadded:: 1.2
+
+.. attribute:: Field.localize
+
+The ``localize`` argument enables the localization of form data, input as well
+as the rendered output.
+
+See the :ref:`format localization <format-localization>` documentation for
+more information.
+
+
Built-in ``Field`` classes
--------------------------
View
7 docs/topics/i18n/localization.txt
@@ -268,6 +268,13 @@ Django uses different formats for different locales when guessing the format
used by the user when inputting data on forms. Note that Django uses different
formats for displaying data, and for parsing it.
+To enable a form field to localize input and output data simply use its
+``localize`` argument::
+
+ class CashRegisterForm(forms.Form):
+ product = forms.CharField()
+ revenue = forms.DecimalField(max_digits=4, decimal_places=2, localize=True)
+
Creating custom format files
----------------------------
View
15 tests/regressiontests/i18n/forms.py
@@ -3,16 +3,19 @@
from models import Company
class I18nForm(forms.Form):
- decimal_field = forms.DecimalField()
- float_field = forms.FloatField()
- date_field = forms.DateField()
- datetime_field = forms.DateTimeField()
- time_field = forms.TimeField()
- integer_field = forms.IntegerField()
+ decimal_field = forms.DecimalField(localize=True)
+ float_field = forms.FloatField(localize=True)
+ date_field = forms.DateField(localize=True)
+ datetime_field = forms.DateTimeField(localize=True)
+ time_field = forms.TimeField(localize=True)
+ integer_field = forms.IntegerField(localize=True)
class SelectDateForm(forms.Form):
date_field = forms.DateField(widget=SelectDateWidget)
class CompanyForm(forms.ModelForm):
+ cents_payed = forms.DecimalField(max_digits=4, decimal_places=2, localize=True)
+ products_delivered = forms.IntegerField(localize=True)
+
class Meta:
model = Company
View
3  tests/regressiontests/i18n/tests.py
@@ -409,7 +409,8 @@ def test_localized_input(self):
self.assertEqual(localize_input(datetime.datetime(2009, 12, 31, 6, 0, 0)), '31.12.2009 06:00:00')
self.assertEqual(datetime.datetime(2009, 12, 31, 6, 0, 0), form6.cleaned_data['date_added'])
settings.USE_THOUSAND_SEPARATOR = True
- self.assert_(u'12.000' in form6.as_ul())
+ # Checking for the localized "products_delivered" field
+ self.assert_(u'<input type="text" name="products_delivered" value="12.000" id="id_products_delivered" />' in form6.as_ul())
finally:
deactivate()
Please sign in to comment.
Something went wrong with that request. Please try again.