[Answered ]-Use different decimal separators for frontend validation in Django Admin interface

1👍

Patch the to_python method, or use a custom form field class that overrides that method.

One-liner answer:

self.fields[key].to_python = lambda v: self.fields[key].__class__.to_python(self.fields[key], '.'.join(v.rsplit(',', 1)) if len(v.rsplit(',', 1)[-1]) < 3 else v)

As a wrapper function:

self.fields[key].to_python = allow_comma_decimal_separator(self.fields[key].to_python)
def allow_comma_decimal_separator(old_to_python):
    def to_python(value):
        if ',' in value:
            lvalue, decimals = value.rsplit(',', 1)
            if len(decimals) < 3:
                value = '.'.join((lvalue, decimals))
        return old_to_python(value)
    return to_python

i.e. If a comma is in the value, and the substring after the rightmost comma has a length of less than 3 (so we assume it’s not a thousand separator), then we replace that comma with a period by joining the substring before and after with a period.

For explicit fields using a reusable form field class

This would be considered less "hacky".

class AllowCommaDecimalSeparatorFloatField(forms.FloatField):

    def to_python(self, value):
        if ',' in value:
            lvalue, decimals = value.rsplit(',', 1)
            if len(decimals) < 3:
                value = '.'.join((lvalue, decimals))
        return super().to_python(value)

In your form’s Meta class:

field_classes = {
    'myfield': AllowCommaDecimalSeparatorFloatField,
}

For all FloatFields

To affect all FloatField instances (not instantiated yet), place this at the top of your module:

old_to_python = forms.FloatField.to_python


def to_python(self, value):
    if ',' in value:
        lvalue, decimals = value.rsplit(',', 1)
        if len(decimals) < 3:
            value = '.'.join((lvalue, decimals))
    return old_to_python(self, value)


forms.FloatField.to_python = to_python
👤aaron

Leave a comment