我在我的Django模型中存储了一些浮点数据,只有一定范围的值才有意义。因此,我想在模型和SQL约束级别强加这些限制。
例如,我想做这样的事情:
class Foo(Model):
myfloat = FloatField(min=0.0, max=1.0)
我想在模型级别而不是表单级别执行此操作。事实上,我可能希望表单级别具有不同的范围;例如,在表单级别使用百分比[0,100],但在模型中转换为[0,1]。
这是可能的,如果可以的话,我该怎么做呢?
答案 0 :(得分:92)
到目前为止,答案描述了如何使表单验证。您还可以在模型中放置验证器。使用MinValueValidator和MaxValueValidator。
例如:
from django.core.validators import MaxValueValidator, MinValueValidator
...
weight = models.FloatField(
validators=[MinValueValidator(0.9), MaxValueValidator(58)],
)
我认为不会增加SQL约束,等等。
答案 1 :(得分:14)
如果您需要在表单级别设置约束,则可以将min_value
和max_value
传递给form field:
myfloat = forms.FloatField(min_value=0.0, max_value=1.0)
但是如果你需要将它移到模型级别,你必须扩展基础models.FloatField
类
class MinMaxFloat(models.FloatField):
def __init__(self, min_value=None, max_value=None, *args, **kwargs):
self.min_value, self.max_value = min_value, max_value
super(MinMaxFloat, self).__init__(*args, **kwargs)
def formfield(self, **kwargs):
defaults = {'min_value': self.min_value, 'max_value' : self.max_value}
defaults.update(kwargs)
return super(MinMaxFloat, self).formfield(**defaults)
然后你可以在模特中使用它
class Foo(models.Model):
myfloat = MinMaxFloat(min_value=0.0, max_value=1.0)
答案 2 :(得分:0)
已经有一段时间了,社区投票的答案已经足够好,基于 Django 内置程序,但这里有另一种方法,特定于问题,遵循 Django Project's documentation。
# app/models.py or create another file for custom validators, i.e. app/custom_validators.py
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _ # use if you support internationalization
def validate_interval(value):
if value < 0.0 or value > 1.0:
raise ValidationError(_('%(value)s must be in the range [0.0, 1.0]'), params={'value': value},)
# app/models.py
class Foo(models.Model):
myfloat = models.FloatField(validators=[validate_interval])
您甚至可以使验证器参数更通用。
请记住,任何验证器都是在表单的 clean()
方法期间调用的。
I.E.如果您尝试不使用表单直接创建对象,您的验证器将不会被调用。
有些人不推荐它,但如果您想在创建对象时调用验证器,请重写 save 方法。
# app/models.py
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _ # use if you support internationalization
class Foo(models.Model):
def save(self, *args, **kwargs):
self.full_clean() # or clean
super().save(*args, **kwargs)
def validate_interval(value):
if value < 0.0 or value > 1.0:
raise ValidationError(_('%(value)s must be in the range [0.0, 1.0]'), params={'value': value},)
myfloat = models.FloatField(validators=[validate_interval])