djangoexceptiondjango-modelsdjango-constraints

Django `UniqueConstraint` exception handled the same as 'unique=True'


When UniqueConstraint of a model is violated, an exception is raised. How can I make it to behave the same as violation of a field with unique=True?

identifier = models.CharField("id", max_length=30, unique=True, blank=True, null=True, validators=[validate_id])

class Meta:
    constraints = [
        models.UniqueConstraint(
            Lower("identifier"),
            name="id_case_insensitive_constraint"
        )
    ]

Here I want a form's form_invalid called with the same field errors and all that, whether the input is exactly the same as another one or its only difference is case distinction.


Solution

  • The constraints are not translated into validators: the validation is done entirely at the database side, so Django can not know in advance that the item will be invalid.

    You can make a validator, for example in the ModelForm to validate this yourself, with:

    from django import forms
    from django.core.exceptions import ValidationError
    
    class MyModelForm(forms.ModelForm):
        
        def clean_identifier(self):
            data = self.cleaned_data['identifier']
            if MyModel.objecs.exclude(pk=self.instance.pk).filter(identifier__iexact=data).exists():
                raise ValidationError('The identifier already exists')
            return data
        
        class Meta:
            model = MyModel
            fields = ['identifier']