django – Single CPF but with blank=True

Question:

if i define

cpf = models.CharField(max_length=11, unique=True, null=True, blank=True)

It turns out that if I leave a record with a null value, when I try to save a second record, it shows a duplicate value.

How to get around this situation?

Answer:

If you set unique=True means you cannot repeat any value, even NULL . The solution to this problem is to do a check before saving, if there are repeated it returns an error to the users.

In forms.py you can check it as follows:

class SeuModelForm(forms.ModelForm):

    class Meta():
        model = SeuModel

    def __init__(self, *args, **kwargs):
        super(SeuModelForm, self).__init__(*args, **kwargs)
        if 'instance' in kwargs:
            self.id = kwargs['instance'].id
        else:
            self.id = None

    def clean(self):
        cleaned_data = super(SeuModelForm, self).clean()
        cpf = cleaned_data.get('cpf')
        if cpf:
            try:
                SeuModel.objects.exclude(id=self.id).get(cpf=cpf)
            except (SeuModel.DoesNotExist):
                pass
            else:
                self.add_error('cpf', u'Este CPF já foi cadastrado')

UPDATE:

After doing a research I found that the problem was not with Django, so the bank accepts more than one NULL . To solve this problem more simply, just return None if the field has not been filled out.

class SeuModelForm(forms.ModelForm):

    class Meta():
        model = SeuModel

    def clean_cpf(self):
        return self.cleaned_data['cpf'] or None

Or even better , directly in the save() method of the model:

def save(self, *args, **kwargs):
    if not self.cpf:
        self.cpf = None
    super(SeuModel, self).save(*args, **kwargs)
Scroll to Top