Models

A model is a Python class that describes one kind of data your app stores — its fields, their types, any constraints. Django turns that class definition into an actual database table, and generates a full Python API for reading and writing rows in it.

Defining a model

Python blog/models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()
    published = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

Each class attribute is a field, and its type — CharField, TextField, BooleanField, DateTimeField — tells Django both what column type to create in the database and how to validate the value in Python. CharField requires max_length; auto_now_add=True means Django fills that field in automatically the moment a row is created, with no code required.

Migrations: turning a model into a table

Defining Post doesn't touch the database by itself — that's a two-step process, generating a migration and then applying it:

Terminal
python manage.py makemigrations
python manage.py migrate
Output
Migrations for 'blog':
  blog/migrations/0001_initial.py
    - Create model Post

Operations to perform:
  Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
  Applying blog.0001_initial... OK

makemigrations looks at your models, compares them to what it last saw, and writes a migration file describing the difference — here, "create a table for Post." migrate is the step that actually runs the SQL against your database. Both are required; running only the first one leaves your models defined in Python but not yet backed by real tables.

Creating and saving a row

Django's shell gives you a live Python prompt with your models already imported and ready:

Terminal
python manage.py shell
Python Django shell
>>> from blog.models import Post
>>> post = Post(title="Hello, Django", body="My first post.")
>>> post.save()
>>> Post.objects.count()
1

post.save() is what actually writes the row — creating a Post object alone only builds it in memory. Post.objects is the model's "manager," your entry point for every query — covered fully in lesson 8.

Note: every time you change a model — add a field, rename one, change a type — you need a fresh makemigrations + migrate pair, even for a field you've already deployed elsewhere. Forgetting this is one of the most common Django beginner errors, and it shows up as a database error complaining about a column that "doesn't exist" even though it's right there in your models.py.