A migration is a small Python file that describes one change to the database schema — add this column, drop this index, rename this table. Migrations are source code you commit. Anyone who runs python manage.py migrate replays the migrations they haven't applied yet, in order, and ends up with the same schema as you.
Two commands matter:
makemigrations — diffs your models against the previous migration state and writes a new migration file. It does not touch the database.migrate — applies pending migrations to the database.Think of it this way: your models.py is the state you want; the migration files are the change history that moves the database from one state to the next. Django records which migrations have run in the django_migrations table.
The most common Django trap: you edit models.py and forget to run makemigrations. The code looks right and the model looks updated, but the database knows nothing about it. Tests run with --keepdb will hide the problem.
This PR added four fields to UserFeed. Running makemigrations produced 0014_userfeed_scheduling_fields.py, a list of migrations.AddField(...) operations. That file is committed next to the model change — the two always travel together.
operations = [
migrations.AddField(
model_name="userfeed",
name="next_check_at",
field=models.DateTimeField(blank=True, db_index=True, null=True),
),
...
]
0014_userfeed_scheduling_fields.py and match each AddField to the corresponding line in models.py. Note that default="" shows up in the operation but db_index=True becomes its own CREATE INDEX step.
Done when: you can describe what SQL Django will run for each operation.makemigrations, look at the file, then delete the field, delete the migration file, and re-run makemigrations to see Django produce nothing. (Don't migrate it.) Get a feel for the diff-based generation.
Done when: you've watched the migration file appear and disappear in response to model changes.RunPython — find a migration in this repo or another Django project that uses migrations.RunPython. That's how data migrations (not just schema) are expressed.
Done when: you can name the difference between a schema migration (AddField, AlterField) and a data migration (RunPython, RunSQL).