Django Models Introduction
What are Django Models?
In Django, models are Python classes that represent database tables. They form the foundation of how your application interacts with your database. Models define the structure of stored data, including field types, constraints, and relationships between different tables.
Django uses an Object-Relational Mapper (ORM) system that sits between your models and the database, allowing you to work with your data using Python objects instead of writing raw SQL. This abstraction makes database operations more intuitive and less error-prone for developers.
Why Models Matter
Models are central to Django's "Model-View-Template" architecture:
- They contain the essential fields and behaviors of the data you're storing
- They define how data is structured and validated
- They provide a Python API to query your database
- They allow you to focus on your data structure rather than SQL syntax
Creating Your First Model
Let's create a simple blog model to understand how Django models work. In Django, models are defined in each app's models.py
file.
# blog/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
published_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
In this example:
- We create a
Post
class that inherits frommodels.Model
- We define three fields:
title
,content
, andpublished_date
- We override the
__str__
method to provide a human-readable representation of our model instances
Common Field Types
Django provides many field types to represent different kinds of data:
Field Type | Description | Example |
---|---|---|
CharField | Short to medium-length strings | title = models.CharField(max_length=100) |
TextField | Large text content | content = models.TextField() |
IntegerField | Integer values | views = models.IntegerField(default=0) |
BooleanField | True/False values | is_published = models.BooleanField(default=False) |
DateTimeField | Date and time | created_at = models.DateTimeField(auto_now_add=True) |
EmailField | Email addresses (with validation) | email = models.EmailField() |
FileField | Files | document = models.FileField(upload_to='documents/') |
ImageField | Image files | thumbnail = models.ImageField(upload_to='images/') |
Field Options
Fields can have various options that affect their behavior:
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(
max_digits=10, # Total digits
decimal_places=2, # Decimal places
null=False, # Cannot be NULL in database
blank=False, # Required in forms
default=0.00, # Default value
help_text="Product price in USD" # Help text for forms
)
description = models.TextField(blank=True) # Optional in forms
class Meta:
verbose_name = "Product"
verbose_name_plural = "Products"
ordering = ['name'] # Default ordering
Model Relationships
Django provides three types of relationships between models:
One-to-Many (ForeignKey)
class Author(models.Model):
name = models.CharField(max_length=100)
bio = models.TextField()
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(
Author,
on_delete=models.CASCADE, # Delete books when author is deleted
related_name='books' # Access from Author as author.books.all()
)
def __str__(self):
return self.title
Many-to-Many
class Tag(models.Model):
name = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
tags = models.ManyToManyField(Tag, related_name='articles')
def __str__(self):
return self.title
One-to-One
class User(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField()
def __str__(self):
return self.username
class Profile(models.Model):
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
related_name='profile'
)
bio = models.TextField(blank=True)
birth_date = models.DateField(null=True, blank=True)
def __str__(self):
return f"{self.user.username}'s profile"
Activating Models
After creating your models, you need to tell Django to create the corresponding database tables:
- Include your app in the
INSTALLED_APPS
list insettings.py
:
INSTALLED_APPS = [
# ...
'blog', # Add your app name here
# ...
]
- Create migrations for your models:
python manage.py makemigrations
This command creates migration files based on your model changes.
- Apply the migrations to create the database tables:
python manage.py migrate
Using Your Models
Once your models are set up and migrated, you can interact with your database:
Creating Objects
# Creating a new post
from blog.models import Post
# Create and save in two steps
post = Post(title='Hello Django', content='This is my first post')
post.save()
# Create and save in one step
Post.objects.create(
title='Learning Models',
content='Django models are powerful!'
)
Querying Objects
# Get all posts
all_posts = Post.objects.all()
# Get a specific post
post = Post.objects.get(id=1) # May raise exceptions if not found
# Filter posts
recent_posts = Post.objects.filter(published_date__year=2023)
# Order posts
ordered_posts = Post.objects.order_by('-published_date') # Newest first
# Complex queries
from django.db.models import Q
search_results = Post.objects.filter(
Q(title__icontains='django') | Q(content__icontains='django')
)
# Count
post_count = Post.objects.count()
Updating Objects
# Update a single object
post = Post.objects.get(id=1)
post.title = "Updated Title"
post.save()
# Update multiple objects
Post.objects.filter(published_date__year=2022).update(title="Archive: 2022")
Deleting Objects
# Delete a single object
post = Post.objects.get(id=1)
post.delete()
# Delete multiple objects
Post.objects.filter(published_date__year=2021).delete()
Real-world Example: E-commerce Store
Let's model a simple e-commerce store:
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
class Meta:
verbose_name_plural = "Categories"
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField(default=0)
available = models.BooleanField(default=True)
category = models.ForeignKey(
Category,
related_name='products',
on_delete=models.CASCADE
)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
def is_in_stock(self):
return self.stock > 0
class Order(models.Model):
STATUS_CHOICES = (
('pending', 'Pending'),
('processing', 'Processing'),
('shipped', 'Shipped'),
('delivered', 'Delivered'),
('canceled', 'Canceled'),
)
customer = models.ForeignKey(User, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
def __str__(self):
return f"Order #{self.id}"
def get_total_cost(self):
return sum(item.get_cost() for item in self.items.all())
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
def __str__(self):
return f"{self.quantity}x {self.product.name}"
def get_cost(self):
return self.price * self.quantity
This example demonstrates:
- Different field types (
CharField
,DecimalField
,BooleanField
, etc.) - Relationships between models (
ForeignKey
) - Custom methods (
is_in_stock
,get_total_cost
,get_cost
) - Using choices for enumeration fields (
STATUS_CHOICES
) - Meta options (
verbose_name_plural
)
Summary
Django models are powerful abstractions that define your data structure and provide an interface to your database. Key points to remember:
- Models are Python classes that inherit from
django.db.models.Model
- Each model maps to a single database table
- Fields define the columns in your database tables
- Django ORM handles the conversion between Python objects and database records
- Relationships between models can be defined using
ForeignKey
,ManyToManyField
, andOneToOneField
- After defining models, you need to create and run migrations to update your database schema
Exercises
- Create a model for a simple blog with posts, comments, and categories
- Add a model for user profiles with custom fields
- Implement a tagging system for your blog posts
- Create models for a library system with books, authors, and loans
- Build a model structure for a social media platform with users, posts, and likes
Additional Resources
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)