Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Models, Views, Admin and Tests  ›  Lesson

models.py and Migrations

models.py 16 minA model class in models.py describes a database table in Python, and migrations are the recorded steps, made by makemigrations and applied by migrate, that bring the real database in line with it.

models.py and Migrations

The cookbook needs somewhere to keep its recipes. You could write CREATE TABLE by hand, then keep the SQL, the Python and every teammate's database in sync forever. Django lets you describe the table once, in Python, and generates the database changes for you, in recorded steps anyone can replay.

The rule

Describe in models.py; makemigrations writes the plan; migrate builds it.

A model is a class that becomes a table. Each field becomes a column:

# recipes/models.py
from django.db import models

class Recipe(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    minutes = models.PositiveIntegerField()
    instructions = models.TextField(blank=True)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

What you get:

  • A table named recipes_recipe (app name, underscore, model name in lower case).
  • An automatic id primary key; you did not write it.
  • Rules in the fields: CharField must have max_length; unique=True forbids two recipes with the same slug; blank=True lets forms leave instructions empty; auto_now_add=True stamps the creation time.
  • __str__ gives each recipe a readable name in the shell and the admin.

Writing the class changes nothing in the database yet. Two commands do that:

python manage.py makemigrations   # writes recipes/migrations/0001_initial.py
python manage.py migrate          # applies it: the table now exists

A migration is a small Python file listing operations such as "create model Recipe" or "add field servings". Migrations are numbered and chained, and Django records which ones each database has applied, so migrate only runs the new ones. Curious what SQL it will run? python manage.py sqlmigrate recipes 0001 prints it.

Migration files are part of your code: commit them. Teammates and servers run migrate and get exactly the same tables.

The shortcut

Every model change is the same three beats: edit, make, migrate. If the database seems out of step with your models, ask which beat was skipped.

Adding servings to RecipeStep 1 of 4
  1. Edit

    Add servings = models.PositiveIntegerField(default=2). Existing rows need a value, hence the default.

The trap is running only makemigrations and wondering why the page crashes with "no such column". The plan is written; it has not been built.

Drills

Answer fast — trust the rule.

quick drill

What does python manage.py makemigrations change in the database?

quick drill

What table does the Recipe model in the recipes app create by default?

quick drill

Which field definition is an error?

quick drill

Should migration files be committed to Git?

quick drill

You added a field and ran makemigrations, but the page says "no such column". What is missing?

Remember

  • Describe in models.py; makemigrations writes the plan; migrate builds it.
  • Edit, make, migrate, then commit the model and the migration together.
  • Trap: a written but unapplied migration means "no such column".

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainAdd a field, safely

The cookbook's Recipe model needs a new servings field. Describe the change to models.py and every command needed until the database has the new column, explaining what makemigrations and migrate each do and which files you commit.