【发布时间】:2011-12-12 03:49:20
【问题描述】:
我在模型中有一个 DecimalField。在与模型关联的 ModelForm 中,我正在尝试自定义字段以允许在处理之前进行简单的数学运算(只是除法)。
例如,我想允许将1/2 输入到表单中,然后将0.50000 保存到数据库中。
在我的表格中:
def clean_qty(self):
data = self.cleaned_data['qty']
if type(data) == int or type(data) ==float: #need to catch decimal too?
return data
elif re.match("^(\d+)/(\d+)$", str(data)):
# do math on, return value
else:
raise forms.ValidationError("Enter number or fraction")
当我使用1/4 提交表单时,我得到“输入一个数字”。并且使用1 会引发“输入数字或分数”作为我的验证错误,这两者都不是我的干净方法中的选项。
我认为它是由 DecimalField 的 to_python 方法引发的?我可以自定义 to_python 字段而无需定义自定义表单字段类型或模型字段类型吗? 或者我还能做些什么来允许这种行为?
解决方案更新:
我最终将 DecimalField 更改为 FloatField。我对 Decimal 类的缺乏经验使它变得异常困难,而且我没有理由需要小数而不是浮点数。另外,按照建议,我在表单中使用了 CharField。
这是验证:
class SomeForm(ModelForm):
qty = forms.CharField(max_length=30)
def clean_qty(self):
data = self.cleaned_data['qty']
try:
float_data = float(data)
return float_data
## this is for integers or floats with no attempted division
except:
try:
match =re.match("(?P<num>([0-9.]+))/(?P<den>([0-9.]+))", str(data))
num = float(match.groupdict()['num'])
den = float(match.groupdict()['den'])
result = num/den
return result
except:
raise forms.ValidationError("Enter a number or fraction")
我真的在使用/滥用 try-except 语法来允许更草率的正则表达式。例如 '。'正则表达式允许分子和分母使用“1.2.3”,但在调用 float() 时会被捕获。所以这很 hackish(在我看来),但我想我会把它发布给其他人。
【问题讨论】:
-
您可以创建带有文本字段的自定义表单。
-
哇...这听起来太容易了,哈哈。我没想过只用一个文本字段来覆盖该字段。我早上试试。我还是想知道修改 to_python 或者其他方法。
-
@akonsu 您应该添加一个答案,因为该评论将我引向正确的方向。我会等待更新我的问题和/或自己回答,具体取决于您的工作。
标签: django django-models django-forms