The IntegrityError: null value in column "field_name" violates not-null constraint means your Django application tried to save a record with a NULL value for a database column that explicitly forbids it, even though your Django model field was configured to allow null=True.

This happens because Django’s ORM and the database schema can get out of sync. The database has a strict NOT NULL constraint on a column, but Django’s model definition might be telling a different story, or a previous migration might have failed to update the schema correctly.

Here are the common causes and how to fix them:

  1. Database Schema Mismatch (Most Common): Your Django model has null=True (or it’s the default for nullable fields like CharField), but the database column was created without allowing NULLs, or a previous migration that should have altered the column to allow NULLs failed.

    • Diagnosis:
      python manage.py dbshell
      
      Then, in your database shell (e.g., psql, mysql):
      -- For PostgreSQL:
      \d your_table_name;
      -- For MySQL:
      DESCRIBE your_table_name;
      
      Look for the specific column (field_name). If it shows NOT NULL or NO under the NULL column, that’s your problem.
    • Fix: Run makemigrations and migrate again. If that doesn’t work, you might need to manually alter the column in the database schema.
      python manage.py makemigrations
      python manage.py migrate
      
      If migration still doesn’t fix it, manually alter the column:
      # For PostgreSQL:
      ALTER TABLE your_table_name ALTER COLUMN field_name DROP NOT NULL;
      
      # For MySQL:
      ALTER TABLE your_table_name MODIFY field_name VARCHAR(255) NULL; -- Replace VARCHAR(255) with your actual field type and max_length
      
      After this, run python manage.py makemigrations again to ensure Django’s migration history reflects the current schema state.
    • Why it works: This directly removes the NOT NULL constraint from the database, aligning it with what your Django model expects.
  2. New Field Added to Existing Table Without Default: You added a new CharField or TextField to an existing model and set null=True and blank=True, but you didn’t provide a default value. When Django tries to create this column on a table that already has rows, it needs to know what value to put in the new column for existing rows. If null=True but no default, the database might balk if it has its own implicit NOT NULL rule for new columns.

    • Diagnosis: Similar to cause 1, check the schema for the new column and see if it’s marked NOT NULL. Also, review your model definition for the new field.
    • Fix: Add a default value to your model field.
      class MyModel(models.Model):
          existing_field = models.CharField(max_length=100)
          # Add a default value
          new_nullable_field = models.CharField(max_length=100, null=True, blank=True, default='')
      
      Then run migrations:
      python manage.py makemigrations
      python manage.py migrate
      
    • Why it works: Providing a default tells the database what value to insert into the new column for all existing rows, satisfying any NOT NULL constraints it might enforce during column creation. An empty string '' is a common default for text fields.
  3. default=None vs. null=True Confusion: Sometimes people set default=None explicitly, thinking it’s the same as null=True. While None can be represented as NULL in the database, default=None on a field that doesn’t have null=True will cause this error. The null=True tells Django to allow NULLs; default=None tells Django what value to use if no value is provided during object creation.

    • Diagnosis: Check your model field definition. If it has default=None but lacks null=True, and the database column is NOT NULL, that’s the issue.
    • Fix: Ensure null=True is present on the model field.
      class MyModel(models.Model):
          # Incorrect if database column is NOT NULL
          # problematic_field = models.CharField(max_length=50, default=None)
      
          # Corrected
          problematic_field = models.CharField(max_length=50, null=True, blank=True, default=None)
          # Or if you want a specific default other than None/NULL:
          # problematic_field = models.CharField(max_length=50, default='')
      
      Then run migrations.
    • Why it works: Explicitly allowing null=True in the Django model definition is crucial for the ORM to generate the correct SQL for databases that support NULL values.
  4. Constraint on a Different Field: The error message might point to field_name, but the actual NOT NULL constraint could be on a related field, especially if you’re using ForeignKey and not setting on_delete or related_name correctly, or if you’re trying to save an object where a related object is None but the foreign key column is NOT NULL.

    • Diagnosis: Examine the traceback carefully. If the error mentions a ForeignKey or OneToOneField, check the model definition of the related model and the database schema for that foreign key column.
    • Fix: Ensure the foreign key field in the database allows NULLs if you intend to have objects without a related instance.
      class RelatedModel(models.Model):
          name = models.CharField(max_length=100)
      
      class MyModel(models.Model):
          # If you want to allow MyModel instances without a RelatedModel
          related_instance = models.ForeignKey(RelatedModel, on_delete=models.SET_NULL, null=True, blank=True)
      
      Run migrations. If the database column is already NOT NULL, you’ll need to manually alter it as in cause 1.
    • Why it works: By setting null=True on the ForeignKey field, you instruct Django to create a nullable foreign key column in the database, which then allows related objects to be optional.
  5. Manual SQL in Migrations: If you have custom SQL in a migration that explicitly sets NOT NULL on a column, but your Django model field has null=True, this will cause a conflict.

    • Diagnosis: Review your migration files in your migrations/ directory for any RunSQL operations that might be altering the column in question.
    • Fix: Either remove the NOT NULL constraint from your custom SQL or update your Django model field to reflect the NOT NULL constraint (remove null=True).
      # Example custom SQL in a migration
      # operations = [
      #     migrations.RunSQL(
      #         "ALTER TABLE your_table_name ALTER COLUMN field_name SET NOT NULL;",
      #         "ALTER TABLE your_table_name ALTER COLUMN field_name DROP NOT NULL;"
      #     ),
      # ]
      
      Modify this SQL to DROP NOT NULL or remove the operation entirely if it conflicts with your model.
    • Why it works: Synchronizing the custom SQL with the model definition ensures both the database schema and Django’s understanding of it are consistent.
  6. Third-Party App Overrides: Sometimes, a third-party Django app might introduce models or migrations that, unintentionally, create NOT NULL constraints that conflict with your local models or expectations.

    • Diagnosis: If the error occurs during installation or migration of a third-party app, examine that app’s models and migration files.
    • Fix: You might need to fork the app and adjust its migrations, or apply manual database schema changes (with caution) to allow NULLs on the problematic column.
    • Why it works: This is a workaround to align the third-party’s schema with your application’s needs.

After applying any of these fixes, remember to run python manage.py makemigrations and python manage.py migrate to ensure your database schema is updated.

The next error you’ll likely hit after fixing this is OperationalError: (1050, "Table 'your_table_name' already exists") if you’ve previously tried to create a table that already exists, or a ManyToManyField related error if you’re dealing with a many-to-many relationship that has its own constraints.

Want structured learning?

Take the full Django course →