Mojimi
Mojimi

Reputation: 3151

Django ValueError: could not convert string to float

Even though I put this line in my settings.py :

LANGUAGE_CODE = 'pt-br'

TIME_ZONE = 'America/Sao_Paulo'

USE_I18N = True

USE_L10N = True

USE_TZ = True

DECIMAL_SEPARATOR = ','

DATE_INPUT_FORMATS = ['%d/%m/%Y']

DATE_FORMAT = r'd/m/Y'

As specified here : https://docs.djangoproject.com/en/1.10/ref/settings/#decimal-separator

Even with L10N set to False it won't recognize(although the language code should already set decimal separator as comma)

Django still won't recognize the comma as decimal separator

Actual error :

ValueError: could not convert string to float: '123,123'

The field is just a default FloatField, I'm not using forms.

What could be causing it to not recognize the comma?

This is the views.py code :

def new_object(request):
    data = json.loads(request.body.decode("utf-8"))
    model_name = data.get('model')
    model = apps.get_model(app_label='cadastroimoveis', model_name=model_name)
    obj = model(**data.get('fields'))
    obj.save()

The sent request is just a JSON with the fields as strings

Edit: I just checked and not even the DATE_INPUT_FORMATS it working, it is still expecting the default values

Upvotes: 3

Views: 4938

Answers (2)

wim
wim

Reputation: 362557

The problem is you seem to be confusing model fields with form fields. The form field offers localization, and it works:

>>> from django.db.models.fields import FloatField
>>> from django.forms.fields import FloatField as FloatFormField
>>> model_field = FloatField()
>>> form_field = model_field.formfield(localize=True)
>>> isinstance(form_field, FloatFormField)
True
>>> form_field.to_python('123,123')
123.123

The model field does not:

>>> model_field.to_python('123,123')
ValidationError: [u"'123,123' value must be a float."]

The model field is nowhere documented as supporting localization, and I can see nothing in the source to suggest that it should be supported.

The line obj = model(**data.get('fields')) shows that you are not using forms at all, you're just consuming a JSON data source and ramming that directly into the model. So, I think the better option for you is to pre-process the JSON data, since Django doesn't seem to support what you're looking for.

You might like to use sanitize_separators helper function, since that's what the forms.fields.FloatField uses to clean the data. Demo:

>>> from django.utils.formats import sanitize_separators
>>> sanitize_separators('123,123')
'123.123'

Upvotes: 7

Gagik Sukiasyan
Gagik Sukiasyan

Reputation: 856

This seems a Django bug and there is something similar reported here

But I'm pretty sure you can overcome this by using forms. I believe, when you try to update that FloatField value in your admin you see : '123.123' and this is because the value is kept in DB's numeric field which cannot support ',' comma. But you can use forms and define form field as follows to see comma instead:

your_field_name = forms.FloatField(localize=True)

By saying localize=True it does 2 things; one to use TextInput instead of NumberInput and also force Django to format the number based on localize settings - doc.

But if you don't use forms, the only way to overcome this is to sanitize you numbers before assigned to model field, and you can use formats.sanitize_separators() function from django.utils:

from django.utils import formats
model.your_field_name = formats.sanitize_separators(value_from_user)
model.save()

Upvotes: 1

Related Questions