Skip to main content

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.

python
# 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 from models.Model
  • We define three fields: title, content, and published_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 TypeDescriptionExample
CharFieldShort to medium-length stringstitle = models.CharField(max_length=100)
TextFieldLarge text contentcontent = models.TextField()
IntegerFieldInteger valuesviews = models.IntegerField(default=0)
BooleanFieldTrue/False valuesis_published = models.BooleanField(default=False)
DateTimeFieldDate and timecreated_at = models.DateTimeField(auto_now_add=True)
EmailFieldEmail addresses (with validation)email = models.EmailField()
FileFieldFilesdocument = models.FileField(upload_to='documents/')
ImageFieldImage filesthumbnail = models.ImageField(upload_to='images/')

Field Options

Fields can have various options that affect their behavior:

python
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)

python
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

python
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

python
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:

  1. Include your app in the INSTALLED_APPS list in settings.py:
python
INSTALLED_APPS = [
# ...
'blog', # Add your app name here
# ...
]
  1. Create migrations for your models:
bash
python manage.py makemigrations

This command creates migration files based on your model changes.

  1. Apply the migrations to create the database tables:
bash
python manage.py migrate

Using Your Models

Once your models are set up and migrated, you can interact with your database:

Creating Objects

python
# 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

python
# 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

python
# 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

python
# 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:

python
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, and OneToOneField
  • After defining models, you need to create and run migrations to update your database schema

Exercises

  1. Create a model for a simple blog with posts, comments, and categories
  2. Add a model for user profiles with custom fields
  3. Implement a tagging system for your blog posts
  4. Create models for a library system with books, authors, and loans
  5. 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! :)