Bram
Bram

Reputation: 3264

Django NULL constraint fails

I want to have an IntegrityError to raise, once a null value is being stored in a field that is not allowing null. The model is as follows:

class Domain(models.Model):
    uuid = models.UUIDField(default=get_hex_uuid, primary_key=True, editable=False)
    name = models.CharField(null=False, max_length=128)

The get_hex_uuid function works, I've tested this. It all fails when I start to save Domain objects as follows:

d = Domain().save()

or

Domain().save()

Clearly both of these should raise an error, as their name value is None/NULL, but it doesn't happen. Now when I select either one of these objects with the Domain.objects.all(), I do get that their name value is stored as

>>> d = Domain.objects.all().first()
>>> d.name
>>> ''

So I started checking at the normal initialise of the Domain object:

>>> d = Domain()
>>> d.name
>>> ''

So apparently it defaults to ''. Why is this? In my earlier experiences, the properties got initialised to None or NULL.

So why does the object property start at ''. How can I fix this?

Upvotes: 0

Views: 49

Answers (2)

Luan Fonseca
Luan Fonseca

Reputation: 1517

I think that you should use the null=true, blank=false in order to have that effect:

class Domain(models.Model):
    uuid = models.UUIDField(default=get_hex_uuid, primary_key=True, editable=False)
    name = models.CharField(max_length=128, null=True)

By doing this, you should expect this behave:

>>> d1 = Domain.objects.create()
>>> print(d1.name)
None
>>> d2 = Domain()
>>> d2.save()
>>> print(d2.name)
None

Which version of django are you using? I am running this code on Django==1.11.7.

Upvotes: 1

Gahan
Gahan

Reputation: 4213

If you want to keep field value unique you can write as below:

name = models.CharField(unique=True, max_length=128)

Note: when you don't mention null, or blank it's default value is False unless you want to allow to store null values in your model you need to use null=True

unique=True will make sure no duplicate record in field entered.

After altering model make sure you apply migrations.

Note: when you execute query from shell not all validation works like blank=False is default value which is used to make sure field is required in django admin but it won't raise any error when you execute same script from shell, you need to overwrite it on your own

To raise exception you need to override save() as follow:

class Domain(models.Model):
    uuid = models.UUIDField(default=get_hex_uuid, primary_key=True, editable=False)
    name = models.CharField(null=False, max_length=128)

    def save(self, *args, **kwargs):
        assert self.name, "The 'name' field can not be null it must be populated."
        super().save(*args, **kwargs)

Upvotes: 1

Related Questions