Python 只允许正十进制数

Python 只允许正十进制数,python,django,Python,Django,在Django模型中,我创建了一个十进制字段,如下所示: price = models.DecimalField(_(u'Price'), decimal_places=2, max_digits=12) 显然,价格为负或为零是没有意义的。有没有办法将十进制数限制为正数 或者我必须使用表单验证来捕获它吗?使用 你可以这样做: # ..... class priceForm(ModelForm): price = forms.DecimalField(required=False, ma

在Django模型中,我创建了一个十进制字段,如下所示:

price = models.DecimalField(_(u'Price'), decimal_places=2, max_digits=12)
显然,价格为负或为零是没有意义的。有没有办法将十进制数限制为正数

或者我必须使用表单验证来捕获它吗?

使用


你可以这样做:

# .....
class priceForm(ModelForm):
    price = forms.DecimalField(required=False, max_digits=6, min_value=0)

这也负责“price”的验证器值。

根据文档,似乎没有办法在字段上设置数据库约束之类的内容。最好的方法是添加模型“验证器”,如果调用模型验证或使用
ModelForm
,将调用该验证器。如果只是将值放入对象并
save()
,则将跳过验证程序

因此,您可以在表单上添加验证,也可以向模型添加验证,如果使用
ModelForm
,模型也可以在表单级别运行

从:

有关如何运行验证程序的更多信息,请参阅 在表单中,以及它们在模型中的运行方式。注 保存模型时验证程序不会自动运行, 但是,如果您使用的是,它将在任何计算机上运行您的验证器 表单中包含的字段。见 有关模型验证如何与表单交互的信息

在Django 2.2中,您可以将其作为数据库表的约束应用于迁移:

从十进制导入十进制
从django.db导入模型
类别项(models.Model):
price=models.DecimalField(u(price)),小数点=2,最大位数=12)
类元:
约束=[
models.CheckConstraint(check=models.Q(price\u gt=Decimal('0')),name='price\u gt\u 0'),
]

约束验证

通常,在
full_clean()
期间不会检查约束,也不会引发
验证错误。相反,在
save()
上会出现数据库完整性错误


假设这是您的产品模型,并且您希望在价格字段上添加非负约束。您可以在模型上添加元约束:

class Product(models.Model):
    price = models.DecimalField(max_digits=13, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        managed = True
        db_table = 'product'
        constraints = [
            models.CheckConstraint(check=models.Q(price__gte='0'), name='product_price_non_negative'),
        ]

或者您可以只添加对表单字段有效的
min\u value=Decimal('0.01')
,但我没有对模型字段测试
min\u value=Decimal('0.01')
。它没有记录在文档中。我将接受更正。我的评论回答了关于表单验证的最后一个问题<代码>最小值
不适用于models.DecimalField.Spot on。如果希望在db中创建对象时触发此验证。重写模型的
save()
方法以运行
self.full\u clean()
class Product(models.Model):
    price = models.DecimalField(max_digits=13, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        managed = True
        db_table = 'product'
        constraints = [
            models.CheckConstraint(check=models.Q(price__gte='0'), name='product_price_non_negative'),
        ]