Django won't apply null=True changes on fields when running makemigrations and migrate
I’m working on a Django project and I’m facing an issue: I modified several fields in one of my models to be null=True, but after running makemigrations and migrate, the changes are not reflected in the database.
I have a model named Sellers with many fields. For example:
class Sellers(models.Model):
...
selling_name = models.CharField(max_length=100, null=True, blank=True)
zip_code = models.IntegerField(null=True, blank=True)
...
However, in the database schema, these fields are still marked as NOT NULL.
What I’ve tried: I created an empty migration manually:
python manage.py makemigrations --empty sellersapp -n fix_nullable_fields
Then manually added AlterField operations like:
migrations.AlterField(
model_name='sellers',
name='selling_name',
field=models.CharField(max_length=100, null=True, blank=True),
),
After running migrate, it said the migration was applied — but still no actual effect on the DB schema.
How can I force Django to apply null=True changes to existing fields in the database? Is there a proper way to generate migrations that actually produce the corresponding ALTER TABLE statements? I’m aware that this issue likely stems from a desynchronization between the database schema and Django’s migration state. However, this is the only inconsistency I need to fix, and I believe this is the cleanest approach to do it without resetting everything.
If there’s a better or safer method to sync the field definitions (null=True) with the actual database schema without losing data, I’d really appreciate any suggestions.
I think this is a common issue in Django when the database schema gets out of sync with the migration history. That's because Django relies on its migration files, not the actual database structure, to decide what changes are needed.
So, if a field was already marked as null=True
in a previous migration, Django assumes there's nothing to change — even if the actual database column is still NOT NULL
. This usually happens due to manual changes in the DB, old migrations being faked or skipped, switching between branches with different migration states ...
If I were in your place, I’d force Django to detect the change by doing what I call a dummy migration (basically a temporary change to "touch" the field):
selling_name = models.CharField(max_length=101, null=True, blank=True)
- Then run:
python manage.py makemigrations
- Now, revert the field back to its correct form:
selling_name = models.CharField(max_length=100, null=True, blank=True)
- Run
makemigrations
again:
python manage.py makemigrations
Django will generate another AlterField
and it should properly include the null=True
update.
- Finally, apply the migration:
python manage.py migrate
That's all I believe.