WesDec WesDec - 9 days ago 6
Python Question

Django: 'unique_together' and 'blank=True'

I have a Django model which looks like this:

class MyModel(models.Model):
parent = models.ForeignKey(ParentModel)
name = models.CharField(blank=True, max_length=200)
... other fields ...

class Meta:
unique_together = ("name", "parent")


This works as expected; If there is the same
name
more than once in the same
parent
then I get an error: "MyModel with this Name and Parent already exists."

However, I also get an error when I save more than one
MyModel
with the same
parent
but with the
name
field blank, but this should be allowed. So basically I don't want to get the above error when the
name
field is blank. Is that possible somehow?

Answer

Firstly, blank (empty string) IS NOT same as null ('' != None).

Secondly, Django CharField when used through forms will be storing empty string when you leave field empty.

So if your field was something else than CharField you should just add null=True to it. But in this case you need to do more than that. You need to create subclass of forms.CharField and override it's clean method to return None on empty string, something like this:

class NullCharField(forms.CharField):
    def clean(self, value):
        value = super(NullCharField, self).clean(value)
        if value in forms.fields.EMPTY_VALUES:
            return None
        return value

and then use it in form for your ModelForm:

class MyModelForm(forms.ModelForm):
    name = NullCharField(required=False, ...)

this way if you leave it blank it will store null in database instead of empty string ('')