'NOT NULL constraint failed' after adding to models.py

I'm using userena and after adding the following line to my models.py

zipcode = models.IntegerField(_('zipcode'),
                                   max_length=5)

I get the following error after I hit the submit button on th signup form:

IntegrityError at /accounts/signup/
NOT NULL constraint failed: accounts_myprofile.zipcode

My question is what does this error mean, and is this related to Userena?


Solution 1:

You must create a migration, where you will specify default value for a new field, since you don't want it to be null. If null is not required, simply add null=True and create and run migration.

Solution 2:

coldmind's answer is correct but lacks details.

The NOT NULL constraint failed occurs when something tries to set None to the zipcode property, while it has not been explicitly allowed.

It usually happens when:

  1. Your field has Null=False by default, so that the value in the database cannot be None (i.e. undefined) when the object is created and saved in the database (this happens after a objects_set.create() call or setting the .zipcode property and doing a .save() call).

    For instance, if somewhere in your code an assignment results in:

    model.zipcode = None
    

    this error is raised.

  2. When creating or updating the database, Django is constrained to find a default value to fill the field, because Null=False by default. It does not find any because you haven't defined any. So this error can not only happen during code execution but also when creating the database?

  3. Note that the same error would be returned if you define default=None, or if your default value with an incorrect type, for instance default='00000' instead of 00000 for your field (maybe can there be an automatic conversion between char and integers, but I would advise against relying on it. Besides, explicit is better than implicit). Most likely an error would also be raised if the default value violates the max_length property, e.g. 123456

    So you'll have to define the field by one of the following:

    models.IntegerField(_('zipcode'), max_length=5, Null=True,
       blank=True)
    
    models.IntegerField(_('zipcode'), max_length=5, Null=False,
       blank=True, default=00000)
    
    models.IntegerField(_('zipcode'), max_length=5, blank=True,
       default=00000)
    

    and then make a migration (python3 manage.py makemigration <app_name>) and then migrate (python3 manage.py migrate).

    For safety you can also delete the last failed migration files in <app_name>/migrations/, there are usually named after this pattern:

    <NUMBER>_auto_<DATE>_<HOUR>.py
    

Finally, if you don't set Null=True, make sure that mode.zipcode = None is never done anywhere.

Solution 3:

if the zipcode field is not a required field then add null=True and blank=True, then run makemigrations and migrate command to successfully reflect the changes in the database.