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
Source:stackexchange.com