[英]Unique together constraint including specific field value
For one of my models, I need to ensure the unicity of some rows, but only in a certain case.对于我的车型之一,我需要保证唯一性的一些行,但只能在特定情况下。 Only the "validated" rows should follow this constraint.
只有“已验证”行应遵循此约束。
Basically, I'm looking forward something like基本上,我期待类似的东西
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'),)
You can use UniqueConstraint in case you're using Django 2.2+ Here is an example如果您使用的是 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')
]
(at time of writing, in Django < 2.2) (在撰写本文时,在 Django < 2.2 中)
You can't do that with unique_together
in Django, presumably because not all db backends would be able to support it.您不能在 Django 中使用
unique_together
来做到这unique_together
,大概是因为并非所有数据库后端都能够支持它。
You can do it in the application layer with model validation instead:您可以使用模型验证在应用程序层执行此操作:
https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects
eg例如
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"
)
Note that you will probably have to call the model validation manually, ie请注意,您可能必须手动调用模型验证,即
instance.clean()
instance.save()
It is not done automatically when saving the model.保存模型时不会自动完成。 On the other hand it is done automatically when using a ModelForm, ie
在另一方面使用的ModelForm时,它是自动完成的,即
if form.is_valid():
instance = form.save()
In addition to the previous answer you can overwrite the save()
method.除了之前的答案,您还可以覆盖
save()
方法。 It would be something like this:它会是这样的:
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
Now you don't need to call the clean()
method.现在您不需要调用
clean()
方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.