【问题标题】:Make Django forms use comma as decimal separator使 Django 表单使用逗号作为小数分隔符
【发布时间】:2010-07-08 11:36:14
【问题描述】:

我正在编写一个 Django 应用程序,以便在他们使用逗号作为 decimal separator 的国家/地区使用。我有一个包含django.db.models.DecimalField 的模型,我使用model forms。如何使生成的表单字段使用逗号呈现并接受用户返回的逗号?

按照jweyrichadvice,我已将我的应用程序从 Django 1.1 升级到 Django 1.2,并编辑了我的 settings.py 以包含以下内容:

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',
)

据我所知,这就是the documentation 所要求的全部。如果我在表单字段上设置localization=True,它现在适用于表单。但是,它既不适用于model forms,也不适用于the admin site

我在 1.2 版本之前发现了 Django ticket 和生成的 Django changeset。如果我理解正确的话,以前小部件会自动使用格式本地化,但在此补丁本地化之后,必须通过向表单字段提供 localization=True 关键字参数来显式打开此补丁本地化。有没有办法让管理表单在他们的字段上设置localization=True

【问题讨论】:

    标签: django


    【解决方案1】:

    是的,确实需要为每个字段明确启用本地化。对于模型表单(包括管理应用程序中使用的表单),一个方便的方法是继承 ModelForm 并为每个 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
    

    然后您可以定义您的自定义 ModelForm 类并在管理应用程序中使用它:

    class FooForm(LocalizedModelForm):
    
        class Meta:
            model = Foo
    
    
    django.admin.site.register(Foo, form=FooForm)
    

    【讨论】:

    • 出色而优雅的解决方案。
    • 我更喜欢把它做成一个 mixin:LocalizationMixin(object): ...FooForm(LocalizationMixin, forms.ModelForm),所以你可以继续使用例如FooForm(LocalizationMixin, floppyforms.ModelForm)
    • 如果你想直接为模型启用本地化怎么办?不是模型表单。用例:查看对发布数据的 AJAX HTTP 请求的响应,并希望将该数据(包含以逗号作为千位分隔符的数字)存储在具有小数字段的模型中。找不到解决方案。
    【解决方案2】:

    在 django >= 1.6 中有一个简单的解决方案:

    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.

    【讨论】:

    • 对于 forms.Form,forms.DecimalField(label='Foo', localize=True) 有效。
    • 'all' 周围的多余括号
    【解决方案3】:

    是的,这看起来像一个令人讨厌的破损,我很惊讶没有人报告。由于您提到的更改,必须为您的管理应用程序或模型表单中的每个字段显式打开本地化。最好的方法是定义一个自定义 ModelForm 以便在管理和应用中使用,并设置 widgets 字典以启用每个相关字段的本地化。

    class MyModelForm(forms.ModelForm):
        class Meta:
            model = MyModel
            widgets = {
                'my_decimal_field': forms.TextInput(attrs={'localization': True}),
            }
    

    【讨论】:

    • 这仅在 HTML 中设置了一个属性,但您让我走上了正确的轨道(结果证明自定义 ModelForm 是要走的路),因此您获得了赏金。谢谢!我会将工作解决方案作为单独的答案发布。
    猜你喜欢
    • 2013-11-03
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-10
    相关资源
    最近更新 更多