唯一约束包括特定字段值(Unique together constraint including specific field value)

对于我的一个模型,我需要确保某些行的唯一性,但仅限于某些情况。 只有“已验证”的行应该遵循这个约束。

基本上,我期待着类似的东西

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'),)

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'),)

最满意答案

你不能在Django中使用unique_together这样做,大概是因为不是所有的db后端都能支持它。

您可以使用模型验证在应用程序层中执行此操作: 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()

保存模型时不会自动完成。 另一方面,它使用ModelForm时自动完成,即

if form.is_valid(): instance = form.save()

You can't do that with unique_together in Django, presumably because not all db backends would be able to support it.

You can do it in the application layer with model validation instead: 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, i.e.

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, i.e.

if form.is_valid(): instance = form.save()唯一约束包括特定字段值(Unique together constraint including specific field value)

对于我的一个模型,我需要确保某些行的唯一性,但仅限于某些情况。 只有“已验证”的行应该遵循这个约束。

基本上,我期待着类似的东西

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'),)

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'),)

最满意答案

你不能在Django中使用unique_together这样做,大概是因为不是所有的db后端都能支持它。

您可以使用模型验证在应用程序层中执行此操作: 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()

保存模型时不会自动完成。 另一方面,它使用ModelForm时自动完成,即

if form.is_valid(): instance = form.save()

You can't do that with unique_together in Django, presumably because not all db backends would be able to support it.

You can do it in the application layer with model validation instead: 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, i.e.

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, i.e.

if form.is_valid(): instance = form.save()