Introduction
Django is one of the most powerful and popular web frameworks built on Python. It encourages a clean and pragmatic approach to building web applications. One of Django’s core strengths lies in its ability to seamlessly handle databases through a feature called Models.
A Django model is a Python class that represents a table in your database. Each attribute of the class corresponds to a field (or column) in that table. Django’s Object-Relational Mapper (ORM) automatically converts Python objects into database records, saving developers from writing raw SQL queries.
In this guide, we’ll walk through every step of creating your first Django model, from writing the class definition to running migrations and exploring the database. By the end, you’ll fully understand how Django models form the foundation of dynamic, data-driven web applications.
1. What Is a Django Model?
A model in Django defines the structure of your database tables. You don’t need to manually write SQL statements; instead, Django handles all database interactions behind the scenes.
Each model:
- Maps directly to a single database table.
- Has class attributes that represent table fields.
- Can interact with data using high-level Python code instead of SQL queries.
In short, models are Django’s way of handling the data layer in its MTV (Model-Template-View) architecture.
When you create a model, Django automatically generates SQL schema definitions and manages migrations — meaning it creates, updates, and deletes database tables as your models evolve.
2. How Models Fit Into Django’s Architecture
To understand why models are so powerful, let’s briefly recall Django’s MTV architecture:
- Model: Defines your data structure.
- Template: Manages how data is presented in HTML pages.
- View: Controls how data flows between the model and the template.
Whenever a user interacts with a Django application (for example, by submitting a form or requesting a page), the view retrieves or updates data through the model. The model communicates with the database, and the view sends that data to a template for rendering.
In essence, models are the heart of your Django project — everything that involves data starts here.
3. Setting Up a Django Project and App
Before defining your first model, you must have a working Django project and app.
Step 1: Create a Django Project
Run this command in your terminal:
django-admin startproject myproject
This creates a folder structure like this:
myproject/
manage.py
myproject/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
Step 2: Create a Django App
Inside your project directory, run:
python manage.py startapp myapp
You now have:
myapp/
admin.py
apps.py
models.py
tests.py
views.py
migrations/
Step 3: Register the App
In myproject/settings.py
, add 'myapp'
to the INSTALLED_APPS
list:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
]
This tells Django to include your app when managing models and migrations.
4. Creating Your First Model
Now comes the exciting part: defining your first Django model.
Open myapp/models.py
and add the following code:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
published_date = models.DateField()
def __str__(self):
return self.title
Let’s Break This Down:
from django.db import models
Imports Django’s model module, which provides all the tools needed to define database models.class Book(models.Model):
Defines a new model calledBook
. Every model class must inherit frommodels.Model
.- Fields:
title
: ACharField
represents a short text field with a maximum length of 100 characters.author
: AnotherCharField
storing the author’s name.published_date
: ADateField
storing a book’s publication date.
__str__
method:
This special method defines what Django should display when you print the model instance or view it in the admin panel. Returningself.title
makes the object easy to identify.
5. Understanding Django Field Types
Each Django model field corresponds to a specific column type in your database. Here are some of the most commonly used field types:
Field Type | Description |
---|---|
CharField | Stores short strings (e.g., names, titles). Requires max_length . |
TextField | For long text fields, like descriptions or articles. |
IntegerField | For whole numbers. |
FloatField | For decimal or floating-point numbers. |
BooleanField | True or False values. |
DateField | For storing dates. |
DateTimeField | For storing both date and time. |
EmailField | A string field that validates email addresses. |
FileField | For uploading files. |
ImageField | For storing image uploads. |
ForeignKey | Creates a relationship with another model (many-to-one). |
ManyToManyField | Defines a many-to-many relationship. |
OneToOneField | Defines a one-to-one relationship. |
Understanding these field types is crucial because they determine how Django creates your database schema and validates data.
6. How Django Maps Models to Database Tables
Each Django model class corresponds to a table in the database:
- The class name (
Book
) becomes the table name (myapp_book
by default). - Each class attribute becomes a column in that table.
- Django automatically adds an
id
field as the primary key unless you specify one.
So, in our Book
model, the database table will have the following structure:
id | title | author | published_date |
---|---|---|---|
1 | Example Book | John Smith | 2025-01-01 |
Django’s ORM handles all interactions — such as creating, reading, updating, or deleting rows — using Python objects.
7. Making Migrations
Once your model is defined, Django needs to create corresponding database tables. This is done in two steps: creating migrations and applying them.
Step 1: Create Migration Files
Run:
python manage.py makemigrations
This command inspects your models and generates migration scripts in the myapp/migrations/
directory. You’ll see output like:
Migrations for 'myapp':
myapp/migrations/0001_initial.py
- Create model Book
Step 2: Apply Migrations
Now run:
python manage.py migrate
This applies all pending migrations to your database and creates the Book
table. Django uses your project’s database settings (by default, SQLite) to perform these operations.
8. Understanding Migrations in Depth
Migrations are Django’s way of synchronizing your model definitions with your database schema.
They allow you to:
- Create tables for new models.
- Modify existing fields.
- Delete old models or fields.
Migrations are version-controlled Python files that can be applied or rolled back easily.
For example, if you modify the Book
model by adding a new field:
isbn = models.CharField(max_length=13, null=True, blank=True)
Then run:
python manage.py makemigrations
python manage.py migrate
Django automatically alters the database table to include this new column. This flexibility allows you to evolve your data model without manually editing SQL.
9. Interacting with Models via the Django Shell
After creating your model and running migrations, you can start working with it using the Django shell.
Run:
python manage.py shell
Then, in the shell:
from myapp.models import Book
# Create a new book
book = Book(title="The Great Gatsby", author="F. Scott Fitzgerald", published_date="1925-04-10")
book.save()
# Retrieve all books
Book.objects.all()
# Get a specific book
Book.objects.get(title="The Great Gatsby")
# Update a record
book.author = "Fitzgerald"
book.save()
# Delete a record
book.delete()
This interactive shell is a powerful tool for testing and exploring your models before integrating them into views or templates.
10. Registering Models in the Django Admin Panel
Django’s built-in admin interface lets you manage your models through a web-based dashboard. To make your model appear there, register it in myapp/admin.py
:
from django.contrib import admin
from .models import Book
admin.site.register(Book)
Now run your development server:
python manage.py runserver
Visit http://127.0.0.1:8000/admin/
and log in. If you don’t have an admin account yet, create one with:
python manage.py createsuperuser
Once logged in, you’ll see Books listed. You can add, edit, and delete book records through a friendly interface without writing a single line of code.
11. QuerySets and Data Retrieval
Django provides an intuitive way to query data through QuerySets.
Common Examples:
# Get all books
Book.objects.all()
# Filter books by author
Book.objects.filter(author="Fitzgerald")
# Get one book
Book.objects.get(id=1)
# Exclude certain results
Book.objects.exclude(author="Unknown")
# Order by date
Book.objects.order_by('-published_date')
QuerySets are lazy, meaning they don’t hit the database until you actually evaluate them (for example, when iterating or converting to a list).
12. Adding Meta Information
Django models allow customization using an inner class called Meta
.
Example:
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
published_date = models.DateField()
class Meta:
ordering = ['-published_date']
verbose_name_plural = 'Books'
def __str__(self):
return self.title
This configuration:
- Orders books by
published_date
descending. - Changes the admin display name from “Bookss” to “Books.”
Meta options improve the usability and readability of your models.
13. Working with Relationships Between Models
Real-world data rarely exists in isolation. Django models can easily represent relationships.
One-to-Many (ForeignKey)
A Book belongs to an Author:
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
Many-to-Many
Books can belong to multiple categories:
class Category(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
categories = models.ManyToManyField(Category)
One-to-One
An Author may have a single Profile:
class Profile(models.Model):
author = models.OneToOneField(Author, on_delete=models.CASCADE)
bio = models.TextField()
Django’s ORM manages all these relationships efficiently without manual SQL joins.
14. Model Inheritance
Django supports inheritance in models, allowing you to reuse and extend existing ones.
Abstract Base Classes
class TimestampedModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Book(TimestampedModel):
title = models.CharField(max_length=100)
This avoids duplication of common fields across multiple models.
15. Customizing Model Managers
You can define custom managers to extend model queries.
Example:
class BookManager(models.Manager):
def published(self):
return self.filter(published_date__isnull=False)
class Book(models.Model):
title = models.CharField(max_length=100)
published_date = models.DateField(null=True, blank=True)
objects = BookManager()
Now you can call:
Book.objects.published()
Custom managers make queries cleaner and more readable.
16. Validating Model Data
Django models automatically perform validation based on field attributes like max_length
or blank=False
. You can also define custom validation methods.
Example:
from django.core.exceptions import ValidationError
class Book(models.Model):
title = models.CharField(max_length=100)
pages = models.IntegerField()
def clean(self):
if self.pages <= 0:
raise ValidationError('Page count must be greater than zero')
Django runs clean()
before saving or during form submission, ensuring your database remains consistent.
17. Using Django Models with Forms and Views
You can easily connect your model to forms and views.
Example:
from django.shortcuts import render
from .models import Book
def book_list(request):
books = Book.objects.all()
return render(request, 'myapp/book_list.html', {'books': books})
Template Example (book_list.html):
<h1>Books</h1>
{% for book in books %}
<p>{{ book.title }} by {{ book.author }}</p>
{% endfor %}
Here, the model interacts with the database, the view processes it, and the template displays it — perfectly illustrating Django’s MTV pattern.
18. Inspecting the Database
To see your models’ database structure, use:
python manage.py dbshell
You can also run:
python manage.py inspectdb
This command generates model definitions from an existing database — very useful when working with legacy systems.
19. Common Mistakes When Defining Models
- Forgetting to Add App to INSTALLED_APPS – Django won’t detect models otherwise.
- Not Running makemigrations and migrate – Your database won’t reflect the latest changes.
- Incorrect Field Types – Using the wrong field for your data (e.g.,
CharField
instead ofTextField
). - Circular Relationships – Avoid mutual dependencies between models.
- Ignoring the str Method – Makes debugging and admin display confusing.
Leave a Reply