我在模型中有一个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
引发'输入数字或分数'作为我的验证错误,这两个都不是我的clean方法中的选项。
我认为它是由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(在我看来),但我想我会发布给其他人。
答案 0 :(得分:1)
使用文本字段创建自定义表单,并在提交表单时将转换为十进制。