[django]限制 django 字段模型中的最大值和最小值

· 收录于 2024-01-06 11:10:07 · source URL

问题详情

假设我有一个模型

class Thing(models.Model):
    rating = models.FloatField()

评级不是由任何用户定义的,而是由脚本计算的,因此它会随着时间的推移一遍又一遍地变化。我还希望它永远不会低于 0 并高于 100(因此,如果它小于 0,则为 0,如果高于 100,则为 100)。

是否可以在模型级别设置此限制,或者我是否需要调整使用此模型的每个脚本以考虑这一点?

最佳回答

是否可以在模型级别设置此限制,或者我是否需要调整使用此模型的每个脚本以考虑这一点?

是的,您可以在使用表单进行验证时使用验证器和约束在数据库端使用验证器和约束来限制该字段:

from django.core.validators import MaxValueValidator, MinValueValidator
from django.db.models import Q


class Thing(models.Model):
    rating = models.FloatField(
        validators=[MinValueValidator(0), MaxValueValidator(100)]
    )

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=Q(rating__range=(0, 100)), name='rating_in_range'
            )
        ]

但这不会截断值,它只会在数据库端(通过约束)以及表单和序列化程序(通过验证器)拒绝它。

例如,我们可以通过重命名字段 _rating 来生成截断逻辑,并让属性处理评级逻辑:

from django.core.validators import MaxValueValidator, MinValueValidator
from django.db.models import Q


class Thing(models.Model):
    _rating = models.FloatField(
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        db_column='rating',
    )

    @property
    def rating(self):
        return self._rating

    @rating.setter
    def rating(self, value):
        self._rating = max(0, min(value, 100))

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=Q(_rating__range=(0, 100)), name='rating_in_range'
            )
        ]