Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make Django forms use comma as decimal separator

Tags:

django

I am writing a Django app for use in a country where they use comma as decimal separator. I have a model that contains a django.db.models.DecimalField, and I use model forms. How can I make the resulting form field render using comma and accept comma back from the user?

Following the advice of jweyrich, I have upgraded my application from Django 1.1 to Django 1.2 and edited my settings.py to contain the following:

LANGUAGE_CODE = 'nb'
LANGUAGES = (
  ('nb', 'Norwegian'),
)
USE_I18N = True
USE_L10N = True
DECIMAL_SEPARATOR = ','
THOUSAND_SEPARATOR = ' '
MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
)

As far as I can see, this is all that the documentation calls for. It now works for forms if I set localization=True on the form field. It works in neither model forms nor the admin site, however.

I discovered a Django ticket and a resulting Django changeset from before the 1.2 release. If I am understanding them correctly, it used to be the case that the widgets used format localization automatically, but after this patch localization has to be turned on explicitly by giving the localization=True keyword parameter to the form field. Is there a way to make admin forms set localization=True on their fields?

like image 989
Vebjorn Ljosa Avatar asked Jul 08 '10 11:07

Vebjorn Ljosa


2 Answers

Yes, localization does need to be turned on explicitly for every field. For a model form (including the ones used in the admin app), a convenient way to do this is to subclass ModelForm and turn on localization for each DecimalField:

import django

class LocalizedModelForm(django.forms.ModelForm):
    def __new__(cls, *args, **kwargs):
        new_class = super(LocalizedModelForm, cls).__new__(cls, *args, **kwargs)
        for field in new_class.base_fields.values():
            if isinstance(field, django.forms.DecimalField):
                field.localize = True
                field.widget.is_localized = True
        return new_class

Then you can define your custom ModelForm class and use it in the admin app:

class FooForm(LocalizedModelForm):

    class Meta:
        model = Foo


django.admin.site.register(Foo, form=FooForm)
like image 150
Vebjorn Ljosa Avatar answered Sep 21 '22 14:09

Vebjorn Ljosa


In django >= 1.6 there is a simple solution to this:

from django.forms import ModelForm

class YourModelForm(ModelForm):
    class Meta:
        model = YourModel
        localized_fields = '__all__'

django.admin.site.register(YourModel, form=YourModelForm)

See the official documentation for a more verbose explanation.

like image 25
zvyn Avatar answered Sep 18 '22 14:09

zvyn