diff --git a/django/forms/fields.py b/django/forms/fields.py
index b31fe80..14152c8 100644
      
        
          
        
        
          
            | a | b | class Field(object): | 
        
        
          
            | 71 | 71 |  | 
          
            | 72 | 72 | def __init__(self, required=True, widget=None, label=None, initial=None, | 
          
            | 73 | 73 | help_text=None, error_messages=None, show_hidden_initial=False, | 
        
        
          
            | 74 |  | validators=[] ): | 
          
            |  | 74 | validators=[], localize=False): | 
        
        
          
            | 75 | 75 | # required -- Boolean that specifies whether the field is required. | 
          
            | 76 | 76 | #             True by default. | 
          
            | 77 | 77 | # widget -- A Widget class, or instance of a Widget class, that should | 
        
        
          
            | … | … | class Field(object): | 
        
        
          
            | 85 | 85 | # initial -- A value to use in this Field's initial display. This value | 
          
            | 86 | 86 | #            is *not* used as a fallback if data isn't given. | 
          
            | 87 | 87 | # help_text -- An optional string to use as "help text" for this Field. | 
        
        
          
            |  | 88 | # error_messages -- An optional dictionary to override the default | 
          
            |  | 89 | #                   messages that the field will raise. | 
        
        
          
            | 88 | 90 | # show_hidden_initial -- Boolean that specifies if it is needed to render a | 
          
            | 89 | 91 | #                        hidden widget with initial value after widget. | 
          
            | 90 | 92 | # validators -- List of addtional validators to use | 
        
        
          
            |  | 93 | # localize -- Boolean that specifies if the field should be localized. | 
        
        
          
            | 91 | 94 | if label is not None: | 
          
            | 92 | 95 | label = smart_unicode(label) | 
          
            | 93 | 96 | self.required, self.label, self.initial = required, label, initial | 
        
        
          
            | … | … | class Field(object): | 
        
        
          
            | 100 | 103 | if isinstance(widget, type): | 
          
            | 101 | 104 | widget = widget() | 
          
            | 102 | 105 |  | 
        
        
          
            |  | 106 | # Trigger the localization machinery if needed. | 
          
            |  | 107 | self.localize = localize | 
          
            |  | 108 |  | 
        
        
          
            | 103 | 109 | # Hook into self.widget_attrs() for any Field-specific HTML attributes. | 
          
            | 104 | 110 | extra_attrs = self.widget_attrs(widget) | 
          
            | 105 | 111 | if extra_attrs: | 
        
        
          
            | … | … | class Field(object): | 
        
        
          
            | 119 | 125 |  | 
          
            | 120 | 126 | self.validators = self.default_validators + validators | 
          
            | 121 | 127 |  | 
        
        
          
            |  | 128 | def localize_value(self, value): | 
          
            |  | 129 | return formats.localize_input(value) | 
          
            |  | 130 |  | 
        
        
          
            | 122 | 131 | def to_python(self, value): | 
          
            | 123 | 132 | return value | 
          
            | 124 | 133 |  | 
        
        
          
            | … | … | class IntegerField(Field): | 
        
        
          
            | 213 | 222 | value = super(IntegerField, self).to_python(value) | 
          
            | 214 | 223 | if value in validators.EMPTY_VALUES: | 
          
            | 215 | 224 | return None | 
        
        
          
            | 216 |  | value = formats.sanitize_separators(value) | 
          
            |  | 225 | if self.localize: | 
          
            |  | 226 | value = formats.sanitize_separators(value) | 
        
        
          
            | 217 | 227 | try: | 
          
            | 218 | 228 | value = int(str(value)) | 
          
            | 219 | 229 | except (ValueError, TypeError): | 
        
        
          
            | … | … | class FloatField(IntegerField): | 
        
        
          
            | 233 | 243 | value = super(IntegerField, self).to_python(value) | 
          
            | 234 | 244 | if value in validators.EMPTY_VALUES: | 
          
            | 235 | 245 | return None | 
        
        
          
            | 236 |  | value = formats.sanitize_separators(value) | 
          
            |  | 246 | if self.localize: | 
          
            |  | 247 | value = formats.sanitize_separators(value) | 
        
        
          
            | 237 | 248 | try: | 
          
            | 238 | 249 | value = float(value) | 
          
            | 239 | 250 | except (ValueError, TypeError): | 
        
        
          
            | … | … | class DecimalField(Field): | 
        
        
          
            | 268 | 279 | """ | 
          
            | 269 | 280 | if value in validators.EMPTY_VALUES: | 
          
            | 270 | 281 | return None | 
        
        
          
            | 271 |  | value = formats.sanitize_separators(value) | 
          
            |  | 282 | if self.localize: | 
          
            |  | 283 | value = formats.sanitize_separators(value) | 
        
        
          
            | 272 | 284 | value = smart_str(value).strip() | 
          
            | 273 | 285 | try: | 
          
            | 274 | 286 | value = Decimal(value) | 
        
      
    
    
      
      diff --git a/django/forms/forms.py b/django/forms/forms.py
index b3718ef..6076065 100644
      
        
          
        
        
          
            | a | b | class BoundField(StrAndUnicode): | 
        
        
          
            | 443 | 443 | name = self.html_name | 
          
            | 444 | 444 | else: | 
          
            | 445 | 445 | name = self.html_initial_name | 
        
        
          
            |  | 446 | if self.field.localize: | 
          
            |  | 447 | data = self.field.localize_value(data) | 
        
        
          
            | 446 | 448 | return widget.render(name, data, attrs=attrs) | 
          
            | 447 | 449 |  | 
          
            | 448 | 450 | def as_text(self, attrs=None, **kwargs): | 
        
      
    
    
      
      diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 8b4112b..082c11b 100644
      
        
          
        
        
          
            | a | b | from django.utils.safestring import mark_safe | 
        
        
          
            | 13 | 13 | from django.utils import formats | 
          
            | 14 | 14 | import time | 
          
            | 15 | 15 | import datetime | 
        
        
          
            | 16 |  | from django.utils.formats import get_format | 
        
        
          
            | 17 | 16 | from util import flatatt | 
          
            | 18 | 17 | from urlparse import urljoin | 
          
            | 19 | 18 |  | 
        
        
          
            | … | … | class Input(Widget): | 
        
        
          
            | 214 | 213 | final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) | 
          
            | 215 | 214 | if value != '': | 
          
            | 216 | 215 | # Only add the 'value' attribute if a value is non-empty. | 
        
        
          
            | 217 |  | final_attrs['value'] = force_unicode( formats.localize_input(value)) | 
          
            |  | 216 | final_attrs['value'] = force_unicode(value) | 
        
        
          
            | 218 | 217 | return mark_safe(u'<input%s />' % flatatt(final_attrs)) | 
          
            | 219 | 218 |  | 
          
            | 220 | 219 | class TextInput(Input): | 
        
        
          
            | … | … | class DateInput(Input): | 
        
        
          
            | 319 | 318 | # formatted by HiddenInput using formats.localize_input, which is not | 
          
            | 320 | 319 | # necessarily the format used for this widget. Attempt to convert it. | 
          
            | 321 | 320 | try: | 
        
        
          
            | 322 |  | input_format = get_format('DATE_INPUT_FORMATS')[0] | 
          
            |  | 321 | input_format = formats.get_format('DATE_INPUT_FORMATS')[0] | 
        
        
          
            | 323 | 322 | initial = datetime.date(*time.strptime(initial, input_format)[:3]) | 
          
            | 324 | 323 | except (TypeError, ValueError): | 
          
            | 325 | 324 | pass | 
        
        
          
            | … | … | class DateTimeInput(Input): | 
        
        
          
            | 350 | 349 | # formatted by HiddenInput using formats.localize_input, which is not | 
          
            | 351 | 350 | # necessarily the format used for this widget. Attempt to convert it. | 
          
            | 352 | 351 | try: | 
        
        
          
            | 353 |  | input_format = get_format('DATETIME_INPUT_FORMATS')[0] | 
          
            |  | 352 | input_format = formats.get_format('DATETIME_INPUT_FORMATS')[0] | 
        
        
          
            | 354 | 353 | initial = datetime.datetime(*time.strptime(initial, input_format)[:6]) | 
          
            | 355 | 354 | except (TypeError, ValueError): | 
          
            | 356 | 355 | pass | 
        
        
          
            | … | … | class TimeInput(Input): | 
        
        
          
            | 381 | 380 | # formatted by HiddenInput using formats.localize_input, which is not | 
          
            | 382 | 381 | # necessarily the format used for this  widget. Attempt to convert it. | 
          
            | 383 | 382 | try: | 
        
        
          
            | 384 |  | input_format = get_format('TIME_INPUT_FORMATS')[0] | 
          
            |  | 383 | input_format = formats.get_format('TIME_INPUT_FORMATS')[0] | 
        
        
          
            | 385 | 384 | initial = datetime.time(*time.strptime(initial, input_format)[3:6]) | 
          
            | 386 | 385 | except (TypeError, ValueError): | 
          
            | 387 | 386 | pass | 
        
        
          
            | … | … | class SplitHiddenDateTimeWidget(SplitDateTimeWidget): | 
        
        
          
            | 771 | 770 | """ | 
          
            | 772 | 771 | is_hidden = True | 
          
            | 773 | 772 |  | 
        
        
          
            | 774 |  | def __init__(self, attrs=None): | 
          
            | 775 |  | widgets = (HiddenInput(attrs=attrs), HiddenInput(attrs=attrs)) | 
          
            | 776 |  | super(SplitDateTimeWidget, self).__init__(widgets, attrs) | 
          
            |  | 773 | def __init__(self, attrs=None, date_format=None, time_format=None): | 
          
            |  | 774 | super(SplitHiddenDateTimeWidget, self).__init__(attrs, date_format, time_format) | 
          
            |  | 775 | for widget in self.widgets: | 
          
            |  | 776 | widget.input_type = 'hidden' | 
          
            |  | 777 | widget.is_hidden = True | 
        
      
    
    
      
      diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt
index 22fabb3..396e510 100644
      
        
          
        
        
          
            | a | b | error message keys it uses. | 
        
        
          
            | 259 | 259 |  | 
          
            | 260 | 260 | ``validators`` | 
          
            | 261 | 261 | ~~~~~~~~~~~~~~ | 
        
        
          
            |  | 262 |  | 
        
        
          
            | 262 | 263 | .. versionadded:: 1.2 | 
          
            | 263 | 264 |  | 
          
            | 264 | 265 | .. attribute:: Field.validators | 
        
        
          
            | … | … | for this field. | 
        
        
          
            | 268 | 269 |  | 
          
            | 269 | 270 | See the :ref:`validators documentation <ref-validators>` for more information. | 
          
            | 270 | 271 |  | 
        
        
          
            |  | 272 | ``localize`` | 
          
            |  | 273 | ~~~~~~~~~~~~ | 
          
            |  | 274 |  | 
          
            |  | 275 | .. versionadded:: 1.2 | 
          
            |  | 276 |  | 
          
            |  | 277 | .. attribute:: Field.localize | 
          
            |  | 278 |  | 
          
            |  | 279 | The ``localize`` argument enables the localization of form data, input as well | 
          
            |  | 280 | as the rendered output. | 
          
            |  | 281 |  | 
          
            |  | 282 | See the :ref:`format localization <format-localization>` documentation for | 
          
            |  | 283 | more information. | 
          
            |  | 284 |  | 
          
            |  | 285 |  | 
        
        
          
            | 271 | 286 | Built-in ``Field`` classes | 
          
            | 272 | 287 | -------------------------- | 
          
            | 273 | 288 |  | 
        
      
    
    
      
      diff --git a/docs/topics/i18n/localization.txt b/docs/topics/i18n/localization.txt
index 10e5923..8e1beae 100644
      
        
          
        
        
          
            | a | b | Django uses different formats for different locales when guessing the format | 
        
        
          
            | 268 | 268 | used by the user when inputting data on forms. Note that Django uses different | 
          
            | 269 | 269 | formats for displaying data, and for parsing it. | 
          
            | 270 | 270 |  | 
        
        
          
            |  | 271 | To enable a form field to localize input and output data simply use its | 
          
            |  | 272 | ``localize`` argument:: | 
          
            |  | 273 |  | 
          
            |  | 274 | class CashRegisterForm(forms.Form): | 
          
            |  | 275 | product = forms.CharField() | 
          
            |  | 276 | revenue = forms.DecimalField(max_digits=4, decimal_places=2, localize=True) | 
          
            |  | 277 |  | 
        
        
          
            | 271 | 278 | Creating custom format files | 
          
            | 272 | 279 | ---------------------------- | 
          
            | 273 | 280 |  | 
        
      
    
    
      
      diff --git a/tests/regressiontests/i18n/forms.py b/tests/regressiontests/i18n/forms.py
index 8ed834c..216d1fe 100644
      
        
          
        
        
          
            | a | b | from django.forms.extras import SelectDateWidget | 
        
        
          
            | 3 | 3 | from models import Company | 
          
            | 4 | 4 |  | 
          
            | 5 | 5 | class I18nForm(forms.Form): | 
        
        
          
            | 6 |  | decimal_field = forms.DecimalField( ) | 
          
            | 7 |  | float_field = forms.FloatField( ) | 
          
            | 8 |  | date_field = forms.DateField( ) | 
          
            | 9 |  | datetime_field = forms.DateTimeField( ) | 
          
            | 10 |  | time_field = forms.TimeField( ) | 
          
            | 11 |  | integer_field = forms.IntegerField( ) | 
          
            |  | 6 | decimal_field = forms.DecimalField(localize=True) | 
          
            |  | 7 | float_field = forms.FloatField(localize=True) | 
          
            |  | 8 | date_field = forms.DateField(localize=True) | 
          
            |  | 9 | datetime_field = forms.DateTimeField(localize=True) | 
          
            |  | 10 | time_field = forms.TimeField(localize=True) | 
          
            |  | 11 | integer_field = forms.IntegerField(localize=True) | 
        
        
          
            | 12 | 12 |  | 
          
            | 13 | 13 | class SelectDateForm(forms.Form): | 
          
            | 14 | 14 | date_field = forms.DateField(widget=SelectDateWidget) | 
          
            | 15 | 15 |  | 
          
            | 16 | 16 | class CompanyForm(forms.ModelForm): | 
        
        
          
            |  | 17 | cents_payed = forms.DecimalField(max_digits=4, decimal_places=2, localize=True) | 
          
            |  | 18 | products_delivered = forms.IntegerField(localize=True) | 
          
            |  | 19 |  | 
        
        
          
            | 17 | 20 | class Meta: | 
          
            | 18 | 21 | model = Company | 
        
      
    
    
      
      diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
index 31150a6..9cc1089 100644
      
        
          
        
        
          
            | a | b | class FormattingTests(TestCase): | 
        
        
          
            | 410 | 410 | self.assertEqual(localize_input(datetime.datetime(2009, 12, 31, 6, 0, 0)), '31.12.2009 06:00:00') | 
          
            | 411 | 411 | self.assertEqual(datetime.datetime(2009, 12, 31, 6, 0, 0), form6.cleaned_data['date_added']) | 
          
            | 412 | 412 | settings.USE_THOUSAND_SEPARATOR = True | 
        
        
          
            | 413 |  | self.assert_(u'12.000' in form6.as_ul()) | 
          
            |  | 413 | # Checking for the localized "products_delivered" field | 
          
            |  | 414 | self.assert_(u'<input type="text" name="products_delivered" value="12.000" id="id_products_delivered" />' in form6.as_ul()) | 
        
        
          
            | 414 | 415 | finally: | 
          
            | 415 | 416 | deactivate() | 
          
            | 416 | 417 |  |