Django 模型 FloatField 错误 'float' 对象没有属性 'as_tuple'



我有一个带有 FloatField 的 Django 模型,后来我基于它制作了一个表单。由于某种原因,我得到"'float'对象没有属性'as_tuple'",不幸的是,我不知道为什么会出现此错误或如何修复它。

models.py:

class Course(models.Model):
title = models.CharField(max_length = 200)
author = models.ForeignKey(User,default=None, on_delete=models.SET_DEFAULT)
description = models.TextField(max_length=1000, blank=True)
tags = models.TextField(blank = True)
duration = models.FloatField(validators=(MinValueValidator(0.1),MaxValueValidator(12), DecimalValidator(max_digits=3,decimal_places=2)))

def __str__(self):
return self.title

forms.py:

class CourseForm(ModelForm):
class Meta:
model = Course
fields = ('title', 'description', 'price', 'duration', 'tags')

views.py:

@login_required
def create_course(request):
if request.method == "POST":
form = CourseForm(request.POST)
if form.is_valid():
form.save()
messages.info(request, f"Course created succesfully!")
else:
messages.error(request, "Something went wrong, please resubmit!")

form = CourseForm()
return render(request, "main/createcourse.html", {"form": form})

.html:

{% extends 'main/header.html' %}
<body>
{% block content%}
<div class="container">
<form method="POST">
{% csrf_token %}
{{form.as_p}}
<br>
<button class="btn" type="submit">Create</button>
</form>
If you to modify an existing course, click <a href="/modify"><strong>here</strong></a> instead.
</div>
<br><br>
{% endblock %}

</body>

如果你真的需要使用FloatField,那么你需要编写自己的验证器:

def validate_decimals(value):
s = str(value)
d = decimal.Decimal(s)
if abs(d.as_tuple().exponent) > 2:
raise ValidationError(
_('%(value)s has more than 2 decimals. Please enter 2 decimals only.'),
params={'value': value},
)

然后,在声明FloatField时添加validators='validate_decimals'

请注意,浮点值不能直接转换为十进制。它应该首先转换为字符串,然后转换为十进制。另请参阅:

Python 浮点型到十进制转换

floatDecimal是有区别的。Decimal通过存储十进制数的数字对数据进行编码。但是,您不能float执行DecimalValidation,因为由于舍入错误,它将添加额外的数字。

因此,你可以改用DecimalField[Django-doc]。请注意,在这种情况下,您需要传递Decimal对象,而不是浮点数。

class Course(models.Model):
title = models.CharField(max_length = 200)
author = models.ForeignKey(User,default=None, on_delete=models.SET_DEFAULT)
description = models.TextField(max_length=1000, blank=True)
tags = models.TextField(blank = True)
duration = models.DecimalField(max_digits=3,decimal_places=2,validators=(MinValueValidator(0.1),MaxValueValidator(12), DecimalValidator(max_digits=3,decimal_places=2)))

def __str__(self):
return self.title

你可能想看看存储持续时间DurationField[Django-doc],但是,这将自动使用timedelta,并将其存储为不支持此类类型的数据库的整数。

最新更新