Skip to main content
Django Basics Tutorial
CHAPTER 08 Beginner

Working with Models and Databases

Updated: May 14, 2026
30 min read

# CHAPTER 8

Working with Models and Databases

1. Introduction

A web application without a database is just a static brochure; it forgets everything the moment the server turns off. To build a blog, e-commerce site, or social network, you must persist data. In this chapter, we will introduce Django's most powerful feature: the Object-Relational Mapper (ORM). We will define database blueprints using Python Classes, execute Django Migrations to automatically generate SQL tables, and explore the default SQLite database.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define a Django Model using Python classes.
  • Understand the concept of an Object-Relational Mapper (ORM).
  • Execute makemigrations and migrate commands.
  • Register models with the Django Admin panel.

3. Beginner-Friendly Explanation

Imagine your Database is an empty Excel spreadsheet. You need to create a table to hold "Blog Posts", with columns for Title, Content, and Date. If you use raw SQL, you have to write complex, error-prone database commands (CREATE TABLE posts (title VARCHAR(100))...). Django Models act as a translator. You simply write a standard Python Class (class Post:), and define variables (title = CharField). The Django ORM reads your Python code, automatically translates it into perfect SQL, and creates the Excel columns for you. You never have to write a single line of SQL!

4. Step 1: Defining a Model

Open blog/models.py. This file is where you define your database schemas. Let's define a blueprint for a Blog Post.
python
12345678910111213
# blog/models.py
from django.db import models
from django.utils import timezone

class Post(models.Model):
    # Define the columns (fields) of the database table
    title = models.CharField(max_length=100) # Short text
    content = models.TextField()             # Long text
    date_posted = models.DateTimeField(default=timezone.now)
    
    # This magic method controls how the object prints in the terminal/admin panel
    def __str__(self):
        return self.title

5. Step 2: Understanding Migrations

We wrote the Python code, but the Database knows absolutely nothing about it yet. We must sync the two. This is a two-step process called Migrations.

Command 1: makemigrations Open your terminal and run:

bash
1
python manage.py makemigrations

*What happened?* Django read your models.py file, saw the new Post class, and created a script (a set of instructions) on how to build that table. It saved this script in the blog/migrations/ folder.

Command 2: migrate Now, we tell Django to actually execute the script and modify the database:

bash
1
python manage.py migrate

*What happened?* Django connected to the database, translated the migration script into SQL, and physically created the blog_post table.

*(Note: The first time you run migrate, Django also creates dozens of built-in tables for its authentication system and admin panel).*

6. The Default Database: SQLite

Wait, where is the database? We didn't install MySQL! Django comes pre-configured to use SQLite3 out of the box. SQLite is a lightweight database that stores everything in a single file on your hard drive. If you look at your root project folder, you will see a new file called db.sqlite3. This file *is* your entire database. It is perfect for local development and learning. (We will cover deploying to PostgreSQL/MySQL in later chapters).

7. Step 3: Registering the Model

To interact with our new database table without writing code, we can use Django's famous built-in Admin panel. But first, we must register the model.

Open blog/admin.py:

python
12345
from django.contrib import admin
from .models import Post

# Register the Post model with the Admin site
admin.site.register(Post)

8. Backend Workflow: Never Touch the Database Manually

If you want to add a new column to your Post table (like author), NEVER open a database GUI (like phpMyAdmin) and manually add the column. If you manually change the database, Django's ORM will fall out of sync, and your application will crash permanently. The Golden Rule: The Python models.py file is the sole source of truth. If you want a new column, you add it to models.py, run makemigrations, and run migrate. Django must manage the database.

9. Best Practices

  • Meaningful _str Methods: Always include the def str(self): method in your models. If you don't, when you query the database, Python will return unreadable garbage like <Post: Post object (1)>. By returning self.title, it will elegantly return <Post: First Post>.

10. Common Mistakes

  • Forgetting makemigrations: Beginners frequently update a model, refresh their browser, and get an OperationalError: no such column. Python code changes instantly upon save, but the database does NOT. Any change to a model requires running the two migration commands.

11. Exercises

  1. 1. Explain the two-step migration process. What is the difference in purpose between makemigrations and migrate?

12. Coding Challenges

  • Challenge: In blog/models.py, add a new field to the Post class called ispublished. Use models.BooleanField(default=False). Save the file, run makemigrations, and run migrate to apply the new column to your SQLite database.

13. MCQs with Answers

Question 1

What is the primary function of the Django ORM (Object-Relational Mapper)?

Question 2

Which manage.py command is responsible for inspecting your Python models and generating a script of the detected changes?

14. Interview Questions

  • Q: Explain the concept of Migrations in Django. Why is it advantageous to store database schema changes as version-controlled Python files rather than executing raw SQL directly against a live database?
  • Q: What is the consequence of manually altering a database schema (e.g., dropping a column via SQL command line) bypassing Django's migration system?

15. FAQs

Q: I made a terrible mistake in my models. Can I just delete the migrations folder? A: NO. Deleting the migrations folder will permanently break your project's ability to sync with the database. If you make a mistake, simply fix the code in models.py and run makemigrations again. Django is smart enough to figure out the fix.

16. Summary

In Chapter 8, we introduced the database layer of the MVT architecture. We defined a Python Class representing a Blog Post and utilized Django's Object-Relational Mapper (ORM) to automatically translate that class into a physical SQLite database table. We mastered the critical two-step workflow of executing makemigrations and migrate to synchronize our Python code with the database schema securely.

17. Next Chapter Recommendation

Our database table exists, but it is empty. How do we create, read, and delete records? Proceed to Chapter 9: Django ORM Basics.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·