1

Having this Django model:

class Subscriber(models.Model):
    email = models.EmailField(unique=True, blank=False)

I do not face any exceptions when creating a Subscriber with empty email:

>>> Subscriber.objects.create(email='')
<Subscriber: Subscriber object>

Interesting is that for the second time it will raise the IntegrityError:

>>> Subscriber.objects.create(email='')
...
IntegrityError: column email is not unique

So it seems to validate for integrity, but neither for email format nor for blank entries. How do I have the email validated?

Vadim Tikanov
  • 631
  • 1
  • 9
  • 26

2 Answers2

5

The parameter blank is used from the form, it's not enforced at database level

From the documentation

Field.blank If True, the field is allowed to be blank. Default is False.

Note that this is different than null. null is purely database-related, whereas blank is validation-related. If a field has blank=True, form validation will allow entry of an empty value. If a field has blank=False, the field will be required.

Indeed the validator documentation says that

Note that validators will not be run automatically when you save a model

to enforce that you have to use the full_clean() method.

The error is thrown because you are trying to insert two times the empty string and you have the unique constraint on the field.

gipi
  • 2,432
  • 22
  • 25
  • Thanks for the answer, now I see why IntegrityError is thrown, however I still do not get why no validation errors are thrown. I've edited my question to be more specific. – Vadim Tikanov Nov 16 '14 at 20:53
  • @VadimTikanov Because as I already wrote, the validators are ran only from the forms not from the model itself. I update the answer with reference to documentation. – gipi Nov 17 '14 at 13:33
  • I used this reference: https://docs.djangoproject.com/en/2.1/ref/models/instances/#validating-objects. Links seem to be dead in this post. – Dave Engineer Dec 19 '18 at 18:09
-1

you got to validate your e-mail field with a built in email-validator like this

from django.core.validators import validate_email

and declare your e-mail field in this way

email = models.EmailField(unique=True, validators=[validate_email,])

this way it will validate your e-mail field with a built in regular expression

abhi
  • 366
  • 6
  • 17
  • This doesn't answer the question. With `blank=False`, the field validator should reject it regardless of whether it is a valid e-mail address. – Arda Xi Nov 16 '14 at 13:18
  • you're not passing blank if you do `type('')` it returns `str` however a blank field should be None its an empty string you are declaring as email not blank. – abhi Nov 16 '14 at 13:25
  • Actually, `str('')` is still a blank `str`, rather than `None`. However, this doesn't change the fact that checking whether it is a valid e-mail address is different from verifying it isn't a blank string. – Arda Xi Nov 16 '14 at 13:29
  • why dont you let the validator take care of the validation it will not match empty strings for sure you can see the regex used [here](https://github.com/django/django/blob/1.5.1/django/core/validators.py#L81) – abhi Nov 16 '14 at 13:32
  • 1
    I imported validate_email, added it to EmailField arguments and run migration. However I can still create Subscriber with email = '' or email = 'aa'. Should I also call the validation method somewhere in the view? – Vadim Tikanov Nov 16 '14 at 20:48
  • @VadimTikanov even I am having the same problem – Harish Kayarohanam Dec 29 '15 at 17:12