mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	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
This commit is contained in:
		| @@ -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 @@ class Field(object): | ||||
|         # 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 @@ class Field(object): | ||||
|         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 @@ 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 | ||||
|  | ||||
| @@ -213,6 +222,7 @@ class IntegerField(Field): | ||||
|         value = super(IntegerField, self).to_python(value) | ||||
|         if value in validators.EMPTY_VALUES: | ||||
|             return None | ||||
|         if self.localize: | ||||
|             value = formats.sanitize_separators(value) | ||||
|         try: | ||||
|             value = int(str(value)) | ||||
| @@ -233,6 +243,7 @@ class FloatField(IntegerField): | ||||
|         value = super(IntegerField, self).to_python(value) | ||||
|         if value in validators.EMPTY_VALUES: | ||||
|             return None | ||||
|         if self.localize: | ||||
|             value = formats.sanitize_separators(value) | ||||
|         try: | ||||
|             value = float(value) | ||||
| @@ -268,6 +279,7 @@ class DecimalField(Field): | ||||
|         """ | ||||
|         if value in validators.EMPTY_VALUES: | ||||
|             return None | ||||
|         if self.localize: | ||||
|             value = formats.sanitize_separators(value) | ||||
|         value = smart_str(value).strip() | ||||
|         try: | ||||
|   | ||||
| @@ -443,6 +443,8 @@ 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): | ||||
|   | ||||
| @@ -13,7 +13,6 @@ from django.utils.safestring import mark_safe | ||||
| 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 @@ 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(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 @@ class DateInput(Input): | ||||
|         # 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 @@ class DateTimeInput(Input): | ||||
|         # 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 @@ class TimeInput(Input): | ||||
|         # 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 | ||||
|   | ||||
| @@ -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 | ||||
| -------------------------- | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| ---------------------------- | ||||
|  | ||||
|   | ||||
| @@ -3,16 +3,19 @@ from django.forms.extras import SelectDateWidget | ||||
| 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 | ||||
|   | ||||
| @@ -409,7 +409,8 @@ class FormattingTests(TestCase): | ||||
|             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() | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user