Django Update Model
Modifying model structure and database schema
🔧 What is Updating a Model?
Updating a model means changing its structure by adding, removing, or modifying fields. Django migrations automatically update your database schema to match your model changes.
# Add a new field to existing model
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField() # New field added
Key Update Concepts
Add Fields
Add new columns to tables
field = models.CharField()
Modify Fields
Change field properties
max_length=200
Remove Fields
Delete columns from tables
# Delete field line
Migrations
Apply changes to database
makemigrations
migrate
🔹 Adding New Fields
Add new fields to your existing model and update the database schema. When adding fields to existing tables, you must provide default values or allow null.
# models.py - Original model
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
# Updated model with new fields
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
description = models.TextField(default='No description') # New field
stock = models.IntegerField(default=0) # New field
created_at = models.DateTimeField(auto_now_add=True) # New field
Run these commands to apply changes:
python manage.py makemigrations
python manage.py migrate
Output:
Migrations for 'myapp':
myapp/migrations/0002_auto_20240115.py
- Add field description to product
- Add field stock to product
- Add field created_at to product
🔹 Modifying Existing Fields
Change properties of existing fields like max_length, default values, or field types:
# Original field
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
# Modified fields
class Product(models.Model):
name = models.CharField(max_length=200) # Increased length
price = models.DecimalField(max_digits=12, decimal_places=2) # More digits
is_active = models.BooleanField(default=True) # Changed default
After modifying fields:
python manage.py makemigrations
python manage.py migrate
🔹 Removing Fields
Delete fields from your model to remove columns from the database:
# Original model
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
old_field = models.CharField(max_length=50) # Will be removed
# Updated model - field removed
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
# old_field deleted
⚠️ Warning:
Removing fields permanently deletes data from that column. Make sure to backup important data first!
Output:
Migrations for 'myapp':
myapp/migrations/0003_remove_product_old_field.py
- Remove field old_field from product
🔹 Adding Fields with Null Values
Allow null values for new fields when you don't want to provide defaults:
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
# New optional fields
description = models.TextField(blank=True, null=True)
discount = models.IntegerField(blank=True, null=True)
image = models.ImageField(upload_to='products/', blank=True, null=True)
Field Options:
- blank=True: Allows empty values in forms
- null=True: Allows NULL in database
- default: Sets default value for existing rows
🔹 Renaming Fields
Rename fields while preserving data:
# Original model
class Product(models.Model):
product_name = models.CharField(max_length=100)
# Renamed field
class Product(models.Model):
name = models.CharField(max_length=100) # Renamed from product_name
Django will ask during makemigrations:
Did you rename product.product_name to product.name? [y/N]
Answer 'y' to preserve the data, or 'N' to create a new field.
🔹 Adding Relationships
Add foreign keys and relationships to existing models:
# Create new related model
class Category(models.Model):
name = models.CharField(max_length=100)
# Update existing model with relationship
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
# New relationship field
category = models.ForeignKey(
Category,
on_delete=models.SET_NULL,
null=True,
blank=True
)
Steps to add relationships:
- Create the related model (Category)
- Add ForeignKey field to existing model
- Run makemigrations and migrate
- Optionally populate the relationship data
🔹 Migration Commands
Essential commands for managing model updates:
# Create migration files
python manage.py makemigrations
# Apply migrations to database
python manage.py migrate
# Show migration status
python manage.py showmigrations
# View SQL for a migration
python manage.py sqlmigrate myapp 0002
# Revert to a specific migration
python manage.py migrate myapp 0001
# Create empty migration for custom changes
python manage.py makemigrations --empty myapp
🔹 Complete Update Example
A real-world example of updating a model:
# Original Product model
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
# Updated Product model with many changes
class Product(models.Model):
# Modified field
name = models.CharField(max_length=200) # Increased length
# Existing field
price = models.DecimalField(max_digits=10, decimal_places=2)
# New fields
sku = models.CharField(max_length=50, unique=True, default='SKU000')
description = models.TextField(blank=True)
stock = models.IntegerField(default=0)
is_active = models.BooleanField(default=True)
# New relationship
category = models.ForeignKey(
'Category',
on_delete=models.SET_NULL,
null=True,
blank=True
)
# New timestamps
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name