Mastering Django Models: A Deep Dive into ORM and Relationships
In this comprehensive guide, we're diving into the essential building block of any Django application: Django Models. We'll explore what models are, how to leverage the powerful Django ORM to interact with your database without writing raw SQL, and walk through practical steps to create your own model and manage data.
I. Understanding Django Models
A Django Model is essentially a simplified method of creating a table in your database using a Python program. It serves as a complete definition of your database table's schema, allowing you to define table properties using standard Python classes and attributes.
Instead of using SQL to define your database structure, you define Python attributes for:
- Column Name
- Data Type
- Constraints
For instance, in an e-commerce project, you define a Product model with fields like name, price, and stock. When you execute the migration command, Django handles the complex SQL to create this table for you.
Note: Django Models can only be created using Python classes, not functions.
II. The Power of Django ORM
ORM stands for Object-Relational Mapper. Django provides its own built-in ORM, which is the preferred method for modern web development.
The Django ORM lets you interact with your database using Python code, eliminating the need to write raw SQL. The ORM writes the necessary SQL for you.
SQL vs ORM this
| Legacy Way (Raw SQL) | Modern Way (Django ORM) | |
|---|---|---|
| Fetch Data | SELECT * FROM table_name WHERE price > 1000 | Product.objects.filter(price__gte=1000) |
| Post Data | INSERT INTO products_product (name, price, description, stock) VALUES ('apple', 95000, 'ios mobile', 10); | new_product_instance = Product( name='apple', price= 95000, descriptions='ios mobile', stock=10 ) new_post_instance.save() |
Why Use Django ORM?
Ease of Use: It's very easy to write.
Cleaner Code: It results in cleaner code compared to lengthy SQL statements.
Security: It provides SQL injection protection, safeguarding against a common web security attack.
III. Creating and Managing a Custom Model (Step-by-Step)
To demonstrate, we’ll create a Product model for an e-commerce site.
A. Model Definition (models.py)
First, define your model class inheriting from models.Model:
#products/models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=200) # Text field with max length
price = models.DecimalField(max_digits=10, decimal_places=2) # Decimal field for currency
description = models.TextField(blank=True) # Text field, allows empty values
stock = models.IntegerField(default=0) # Integer field with a default value
def __str__(self):
return self.name
B. Database Setup and Migration
Before creating your custom table, ensure your base db.sqlite3 file is created. This file is used for development and is often created by running the server or a migration command.
- Create Migration File (Schema): Because this is a custom model, we need Django to prepare the SQL schema.
python manage.py makemigrations
This command generates the migration file inside your app's migrations folder.
- Apply Migration (Create Table): Now, execute the SQL to create the table in your database.
python manage.py migrate
C. Data Interaction via Django Shell
You can interact with your new table using the Django Shell (though the Admin Panel is generally more convenient).
- Open the Shell:
python manage.py shell
- Import the Model:
from products.models import Product
- Post Data (Create):
p = Product(name='Laptop', price=75000, description='Gaming Laptop', stock=10)
p.save() # Saves the new record to the database
- Retrieve Data:
# Retrieve all records
Product.objects.all()
# Filter records (price greater than or equal to 50000)
Product.objects.filter(price__gte=50000)
# Get a specific record by its primary key
Product.objects.get(id=1)
- Update Data:
p = Product.objects.get(id=1) # Get the record
p.stock = 8 # Update the attribute
p.save() # Save the change to the database
IV. Understanding Django Model Relationships
Model relationships define how different tables in your database are linked. Django classifies them into three types:
One-to-One Relationship
- Concept: A record in one table is linked to exactly one record in another table.
- Example: A Person is linked to one Passport.
- Code: The Passport model links to the Person model.
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.DateField()
def __str__(self):
return f"{self.first_name} {self.last_name}"
class Passport(models.Model):
# This creates the one-to-one relationship.
# Each Passport instance is linked to exactly one Person instance.
person = models.OneToOneField(
Person,
on_delete=models.CASCADE,
primary_key=True,
)
passport_number = models.CharField(max_length=20, unique=True)
country = models.CharField(max_length=50)
issue_date = models.DateField()
expiration_date = models.DateField()
def __str__(self):
return f"Passport for {self.person}"
- on_delete=models.CASCADE: If the person is deleted, the passport is also deleted.
- primary_key=True: The person's ID is used as the primary key in the passport table.
Many-to-One Relationship (ForeignKey)
- Concept: Multiple records in one table are linked to one record in another table.
- Example: Multiple Orders can belong to one Customer.
- Code: The Order model links back to the Customer model using a Foreign Key.
from django.db import models
class Customer(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField(unique=True)
def __str__(self):
return f"{self.first_name} {self.last_name}"
class Order(models.Model):
order_date = models.DateField(auto_now_add=True)
total_amount = models.DecimalField(max_digits=10, decimal_places=2)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='orders')
def __str__(self):
return f"Order {self.id} for {self.customer}"
- related_name='orders': Allows the Customer object to easily access all its associated Order records.
- Alternative: Use on_delete=models.SET_NULL if you want to keep the order record but clear the customer link when the customer is deleted.
Many-to-Many Relationship
- Concept: Records in the first table can be linked to multiple records in the second table, and vice-versa.
- Example: Multiple Authors can write one Book, and one Author can write multiple Books.
- Mechanism: Django automatically creates a Junction Table (or intermediary table) to manage these links.
- Code: The Book model links to the Author model.
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200)
authors = models.ManyToManyField(Author)
def __str__(self):
return self.title
- Caution: You cannot use on_delete=models.CASCADE here, as deleting one entity (e.g., an author) should not delete another entity (e.g., a co-authored book).
By mastering Django Models and the ORM, you gain a powerful, Python-centric way to manage your application’s data, making your development process cleaner, faster, and more secure!
Do You Need Side Hustle?
Get Paid to Share Your Opinion: User Interviews Can Get You Quick Cash
Ever heard of User Interviews? It's a platform that pays you for your feedback on products and services. The best part is that you can get a bonus just for signing up and completing your first study. I've already earned money with them, and you can, too.
Click here to sign up and get your bonus! Please wait until Sign Up page load.
Disclaimer: Referral bonus amounts are subject to change. The bonus is awarded after you complete your first paid study and may take a few days to process. All terms and conditions are set by User Interviews, and it's best to check their official site for the most up-to-date program rules.
Earn Cash for Your Opinions and a Bonus to Boot: Try Respondent.io
Respondent is a top platform that pays you for taking part in market research and user interviews. I've used it to find great paid studies, and you can, too. Their referral program is a fantastic way to earn more: when a friend you refer signs up and completes a study, you both get a bonus. It’s a great way to earn a little extra for yourself while helping a friend find paid work.
Click here to sign up and get your bonus!
Disclaimer: Referral bonus amounts and terms are subject to change by Respondent.io. The bonus is typically awarded after the referred friend completes their first paid study. Please check their official referral program page for the most up-to-date details.