繁体   English   中英

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

[英]Django model FloatField error 'float' object has no attribute 'as_tuple'

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

模型.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

表格.py:

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

视图.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通过存储十进制数的数字来对数据进行编码。 但是,您可以执行DecimalValidationfloat ,因为由于舍入误差,这将增加额外的数字。

因此,您可以改用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 ,并将其存储为支持此类类型的数据库的整数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM