python 基于现有模型数据的Django模型唯一约束?

ecbunoof  于 2023-03-11  发布在  Python
关注(0)|答案(1)|浏览(146)

作为Django唯一约束检查的一部分,是否可以引用现有的模型数据?
例如,

class MyModel(models.Model):
    ....
    my_field = models.IntField(...)

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=models.Q(my_field__gte=MyModel.objects.all().last().my_field,
                name="example_constraint" 
        ]

在这个伪代码示例中,我查询MyModel,获取最新的记录,并在添加新的MyModel时使用它的'my_field'属性值作为约束的一部分。

更新

虽然看起来我的伪代码没有达到预期的效果,但我现在想知道是否有可能使用django.db.modelsMax()来达到预期的结果?
例如:

constraints = [
    models.CheckConstraint(
        check=models.Q(my_field__gte=Max(my_field),
        name="example_constraint" 
    ]

这个对Max(my_field)的调用会从现有的数据库行返回my_field的最大值吗?或者只是将my_field的当前示例值传递给Max()函数?

nzkunb0c

nzkunb0c1#

从技术上讲,可以引用现有的模型数据作为Django唯一约束检查的一部分,就像你在伪代码示例中演示的那样。然而,通常不建议这样做。在你的示例中,每次创建MyModel的新示例时,都会执行查询MyModel.objects.all().last(),这可能会消耗大量资源,并降低应用程序的速度。
一个更好的方法是使用自定义验证器来强制约束,而不是依赖查询来获取最新的记录。
从django.core.exceptions导入从django.db导入模型验证错误
类MyModel(模型.模型):my_field =模型.整数字段()

class Meta:
    constraints = [
        models.CheckConstraint(
            check=models.Q(my_field__gte=0),
            name='my_field_positive'
        ),
    ]

def clean(self):
    super().clean()
    last_instance = MyModel.objects.order_by('-id').first()
    if last_instance and self.my_field < last_instance.my_field:
        raise ValidationError('my_field must be greater than or equal to the last instance')

相关问题