如何限制一个Django模型中的数字字段的最大值?

Django有各种数字字段可用于模型,例如DecimalField和PositiveIntegerField 。 虽然前者可以限制在小数点存储的位数和存储的字符总数,但有没有办法限制它只存储一定范围内的数字,例如0.0-5.0?

否则,有没有办法限制PositiveIntegerField只存储,例如,数字高达50?

更新:现在Bug 6845 已经closures ,这个StackOverflow的问题可能是没有意义的。 – sampablokuper

您也可以创build自定义模型字段types – 请参阅http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#howto-custom-model-fields

在这种情况下,您可以从内置的IntegerFieldinheritance并覆盖validation逻辑。

我越想到这一点,我意识到这对许多Django应用程序是多么有用。 也许IntegerRangeFieldtypes可以作为补丁提交给Django开发人员考虑添加到主干。

这对我有用:

from django.db import models class IntegerRangeField(models.IntegerField): def __init__(self, verbose_name=None, name=None, min_value=None, max_value=None, **kwargs): self.min_value, self.max_value = min_value, max_value models.IntegerField.__init__(self, verbose_name, name, **kwargs) def formfield(self, **kwargs): defaults = {'min_value': self.min_value, 'max_value':self.max_value} defaults.update(kwargs) return super(IntegerRangeField, self).formfield(**defaults) 

然后在你的模型类中,你可以像这样使用它(字段是放置上面代码的模块):

 size = fields.IntegerRangeField(min_value=1, max_value=50) 

或者对于一系列负值和正值(如振荡器范围):

 size = fields.IntegerRangeField(min_value=-100, max_value=100) 

真的很酷的是,如果它可以用这样的范围运算符来调用:

 size = fields.IntegerRangeField(range(1, 50)) 

但是,这将需要更多的代码,因为你可以指定一个“跳过”参数 – 范围(1,50,2) – 虽然有趣的想法…

你可以使用Django的内置validation器 –

 from django.db.models import IntegerField, Model from django.core.validators import MaxValueValidator, MinValueValidator class CoolModelBro(Model): limited_integer_field = IntegerField( default=1, validators=[ MaxValueValidator(100), MinValueValidator(1) ] ) 

编辑 :虽然这些只在ModelForm中使用模型时才起作用 ,但如果您是使用“自己的”模型,则不是。

 from django.db import models from django.core.validators import MinValueValidator, MaxValueValidator size = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(5)]) 

我有这个同样的问题。 这是我的解决scheme:

 SCORE_CHOICES = zip( range(1,n), range(1,n) ) score = models.IntegerField(choices=SCORE_CHOICES, blank=True) 

有两种方法可以做到这一点。 一种是使用表单validation,不让任何超过50的数字被用户input。 表单validation文档 。

如果没有用户参与进程,或者您没有使用表单input数据,则必须重写模型的save方法以引发exception或限制数据进入该字段。

如果您想要一些额外的灵活性并且不想改变您的模型领域,这是最好的解决scheme。 只需添加这个自定义validation器:

 #Imports from django.core.exceptions import ValidationError class validate_range_or_null(object): compare = lambda self, a, b, c: a > c or a < b clean = lambda self, x: x message = ('Ensure this value is between %(limit_min)s and %(limit_max)s (it is %(show_value)s).') code = 'limit_value' def __init__(self, limit_min, limit_max): self.limit_min = limit_min self.limit_max = limit_max def __call__(self, value): cleaned = self.clean(value) params = {'limit_min': self.limit_min, 'limit_max': self.limit_max, 'show_value': cleaned} if value: # make it optional, remove it to make required, or make required on the model if self.compare(cleaned, self.limit_min, self.limit_max): raise ValidationError(self.message, code=self.code, params=params) 

它可以这样使用:

 class YourModel(models.Model): .... no_dependents = models.PositiveSmallIntegerField("How many dependants?", blank=True, null=True, default=0, validators=[validate_range_or_null(1,100)]) 

这两个参数是最大值和最小值,它允许空值。 你可以自定义validation器,如果你喜欢摆脱标记的if语句或在模型中将您的字段更改为blank = False,null = False。 那当然需要迁移。

注:我不得不添加validation器,因为Django不validationPositiveSmallIntegerField上的范围,而是为该字段创build一个smallint(在postgres中),如果指定的数字超出范围,则会出现数据库错误。

希望这有助于:)更多关于在Django中的validation器 。

PS。 我在django.core.validators中将我的答案放在BaseValidator上,但除了代码之外,一切都是不同的。