简体   繁体   English

唯一的共同约束,包括特定的字段值

[英]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')
        ]

here is the source这是 来源

(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM