У меня есть 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
вызывает «Ввод числа или дроби» в качестве моей ошибки проверки, ни один из которых не является опцией моего чистого метода.
Я думаю, что он вызывается методом to_python для DecimalField?Могу ли я настроить поле 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-Кроме, чтобы разрешить регулярное выражение sloppier.Например '.'и '1.2.3' разрешено регулярным выражением для числителя и знаменателя, но они попадают при вызове float ().Так что это довольно хакерски (на мой взгляд), но я думал, что выложу это для других.