49

在我的 Django 模型中,我创建了一个像这样的十进制字段:

price = models.DecimalField(_(u'Price'), decimal_places=2, max_digits=12)

显然,价格为负数或为零是没有意义的。有没有办法将十进制数限制为仅正数?

还是我必须使用表单验证来捕获它?

4

6 回答 6

92

使用MinValueValidator.

price = models.DecimalField(_(u'Price'), decimal_places=2, max_digits=12, validators=[MinValueValidator(Decimal('0.01'))])
于 2012-09-12T08:59:45.390 回答
2

你可以做这样的事情:

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

这也负责“价格”的验证者值。

于 2016-09-28T15:48:26.023 回答
1

在 Django 2.2 中,您可以向模型添加约束,该模型将在迁移中作为数据库表的约束应用:

from decimal   import Decimal
from django.db import models

class Item(models.Model):
    price = models.DecimalField( _(u'Price'), decimal_places=2, max_digits=12 )

    class Meta:
        constraints = [
            models.CheckConstraint(check=models.Q(price__gt=Decimal('0')), name='price_gt_0'),
        ]

笔记:

约束验证

一般约束期间不检查full_clean(),也不提出ValidationErrors。相反,您会在save().

于 2019-10-21T14:16:45.673 回答
1

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

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'),
        ]
于 2020-01-29T07:17:49.847 回答
0

根据文档,似乎没有办法在字段上放置诸如数据库约束之类的东西。您可以做的最好的事情是添加模型“验证器”,如果您调用模型验证或使用ModelForm. 如果您只是将值放入对象和save().

因此,您可以在表单上添加验证,或者您可以向模型添加验证,如果您使用ModelForm.

来自“验证器如何运行”的文档

有关验证器如何在表单中运行的更多信息,请参阅表单验证,以及验证对象以了解它们如何在模型中运行。请注意,当您保存模型时,验证器不会自动运行,但如果您使用 a ModelForm,它将在表单中包含的任何字段上运行您的验证器。有关模型验证如何与表单交互的信息,请参阅ModelForm 文档

于 2016-10-03T12:10:23.313 回答
0
  1. 导入依赖
from decimal import Decimal
from django.core.validators import MinValueValidator
  1. 添加验证器
price = models.DecimalField(
 decimal_places=2, 
 max_digits=12, 
 validators=[MinValueValidator(Decimal('0.01'))]
)
于 2022-02-28T12:46:14.047 回答