I have the following model:
class User(models.Model):
email = models.EmailField(max_length=254, null=False, unique=True)
referral_code = models.CharField(max_length=10, null=False, unique=True)
And used the Django shell to save a user instance with referral_code undefined:
u = User(email="[email protected]")
u.save()
This did not raise an exception. My understanding was that null=False would require referral_code to be set - Is this not the case? How would I achieve that behaviour?
update
I notice that the field is set to u.referral_code=''
, so given the uniqueness constraint, this has raised an exception when I tried to repeat the process with a new instance. I would rather the exception was thrown because I did not set the field...
The value of your referral_code
is not null
, it is ''
(blank string). This is the default of CharField
.
Updated along with question:
You can raise an error before the data is stored in the database by overriding save
on the model
class User(models.Model):
email = models.EmailField(max_length=254, null=False, unique=True)
referral_code = models.CharField(max_length=10, null=False, unique=True)
def save(self, *args, **kwargs):
assert self.email, "The 'email' field must be populated."
super().save(*args, **kwargs)
It should be noted that this is not to be preferred over form validation where possible.
Update now that newer features of Django are available:
Django's Constraints allow you to add custom database constraints:
class User(models.Model):
email = models.EmailField(max_length=254, null=False, unique=True)
referral_code = models.CharField(max_length=10, null=False, unique=True)
class Meta:
constraints = [
models.CheckConstraint(
check=(~models.Q(referral_code='')),
name='referral_code_populated',
)
]