对于我的一个模型,我需要确保某些行的单性,但仅限于特定情况。 只有"已验证"行才应遵循此约束。
基本上,我期待着类似的东西
class MyModel(models.Model):
field_a = models.CharField()
field_b = models.CharField()
validated = models.BooleanField(default=False)
class Meta:
unique_together = (('field_a', 'field_b', 'validated=True'),)
如果你使用的是 Django 2.2+,你可以使用 UniqueConstraint这是一个例子
class MyModel(models.Model):
field_a = models.CharField()
field_b = models.CharField()
validated = models.BooleanField(default=False)
class Meta:
constraints = [
UniqueConstraint(fields=['field_a', 'field_b'], condition=Q(validated=True), name='unique_field_a_field_b_validated')
]
这是来源
(在撰写本文时,在 Django <2.2 中)
你不能在 Django 中使用 unique_together
做到这一点,大概是因为并非所有的数据库后端都能够支持它。
您可以在应用程序层中使用模型验证来执行此操作:
https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects
例如
class MyModel(models.Model):
field_a = models.CharField()
field_b = models.CharField()
validated = models.BooleanField(default=False)
def clean(self):
if not self.validated:
return
existing = self.__class__.objects.filter(field_a=self.field_a,
field_b=self.field_b).count()
if existing > 0:
raise ValidationError(
"field_a and field_b must be unique if validated=True"
)
请注意,您可能必须手动调用模型验证,即
instance.clean()
instance.save()
保存模型时不会自动完成。另一方面,当使用模型表单时,它是自动完成的,即
if form.is_valid():
instance = form.save()
除了前面的答案之外,您还可以覆盖save()
方法。它会是这样的:
def save(self, **kwargs):
try:
self.objects.get(field_a=self.field_a, field_b=self.field_b, validated=True)
# The object already exist therefore throw an exception
raise ValidationError(
"field_a and field_b must be unique if validated=True"
)
except self.__class__.DoesNotExist: # Save the model
super(MyModel, self).save(**kwargs) # inherit and call the save method
现在,无需调用 clean()
方法。