Django ValueError:无法将字符串转换为浮点数

Posted

技术标签:

【中文标题】Django ValueError:无法将字符串转换为浮点数【英文标题】:Django ValueError: could not convert string to float 【发布时间】:2017-08-09 10:43:43 【问题描述】:

即使我将这一行放在我的 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'

这里指定:https://docs.djangoproject.com/en/1.10/ref/settings/#decimal-separator

即使将 L10N 设置为 False,它也无法识别(尽管语言代码应该已经将小数分隔符设置为逗号)

Django 仍然无法将逗号识别为小数分隔符

实际错误:

ValueError:无法将字符串转换为浮点数:'123,123'

该字段只是一个默认的 FloatField,我没有使用表单。

什么可能导致它无法识别逗号?

这是views.py代码:

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()

发送的请求只是一个 JSON 格式的字符串

编辑:我刚刚检查过,甚至 DATE_INPUT_FORMATS 都没有工作,它仍然需要默认值

【问题讨论】:

可能的原因:请注意,如果 USE_L10N 设置为 True,则区域设置格式具有更高的优先级并将被应用。 ? @nik_m 已经尝试过了,但我的语言环境设置实际上应该将逗号定义为分隔符 看过这个this question? @JensAstrup 这就是 Django 应该做的,它是十进制的,而不是千位 能否请您发布出现错误的代码? 【参考方案1】:

问题是您似乎将模型字段与表单字段混淆了。表单字段提供本地化,并且有效:

>>> 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

模型字段没有:

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

模型字段在任何地方都没有记录为支持本地化,我在source 中看不到任何内容表明应该支持它。

obj = model(**data.get('fields')) 行表明您根本没有使用表单,您只是在使用 JSON 数据源并将其直接加载到模型中。所以,我认为对您来说更好的选择是预处理 JSON 数据,因为 Django 似乎不支持您正在寻找的内容。

您可能希望使用sanitize_separators 辅助函数,因为that's what the forms.fields.FloatField uses 可以清理数据。演示:

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

【讨论】:

你说得对,我猜模型和表单很容易混淆,我一直在看表单的字段源代码 只是扩展主题,如果我想对日期做同样的事情,正确的方法是django.utils.dateparse ? 我以为L10n版本好像是utils.formats.date_format date_format 需要一个类似日期的对象并返回一个格式化的字符串,它恰恰相反,找不到用于清理日期输入并将其本地化的表单 哦,对了。那么DateTimeField(来自表单)使用自定义strptime 方法,使用self.input_formats 中解析的第一种格式。【参考方案2】:

这似乎是一个 Django 错误,并且有类似的报告 here

但我很确定您可以通过使用表单来克服这个问题。我相信,当您尝试在管理员中更新 FloatField 值时,您会看到:“123.123”,这是因为该值保存在数据库的数字字段中,无法支持“,”逗号。但是您可以使用表单并按如下方式定义表单字段来查看逗号:

your_field_name = forms.FloatField(localize=True)

localize=True 它做了两件事;一种是使用 TextInput 而不是 NumberInput 并且还强制 Django 根据本地化设置格式化数字 - doc。

但如果您不使用表单,唯一的解决方法是在分配给模型字段之前对您的数字进行清理,您可以使用django.utils 中的formats.sanitize_separators() 函数:

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

【讨论】:

以上是关于Django ValueError:无法将字符串转换为浮点数的主要内容,如果未能解决你的问题,请参考以下文章

ValueError:无法引用参数值 <django.contrib.postgres.fields.jsonb.JsonAdapter

Django - Celery ValueError:无法解析相关模型 u'user.User'

ValueError:无法将字符串转换为浮点数:'GIAC'

ValueError:无法将字符串转换为浮点数:'Bad'

ValueError:无法将字符串转换为浮点数:'2100 - 2850'

Python:ValueError:无法将字符串转换为浮点数:'0'