Django by Example: Model Default Values
Setting default values for model fields is a common requirement. This sample code shows how Django allows you to specify static values or callable functions to generate defaults dynamically when a new object is created.
Code
from django.db import models
import uuid
from django.utils import timezone
def generate_sku():
return str(uuid.uuid4()).upper()[:10]
class Order(models.Model):
# Static default value
status = models.CharField(
max_length=20,
default='pending',
choices=[
('pending', 'Pending'),
('shipped', 'Shipped'),
('delivered', 'Delivered')
]
)
# Static integer default
priority = models.IntegerField(default=0)
# Callable default (executed when object is created)
order_id = models.CharField(max_length=10, default=generate_sku, unique=True)
# Callable from standard library
ordered_at = models.DateTimeField(default=timezone.now)
# Empty list/dict default for JSONField requires a callable
# Do NOT use default={} or default=[] as they are mutable
extra_data = models.JSONField(default=dict)
def __str__(self):
return f"Order {self.order_id}"Explanation
The default argument allows you to provide a value for a field if one isn't specified during model instance creation. This feature is critical for ensuring data consistency and simplifying object creation logic, allowing you to instantiate models with minimal arguments. Starting with Django 5.0, you can also use db_default to define defaults at the database level, which is useful when other applications or scripts interact with your database directly.
Defaults can be specified as static values (like strings, numbers, or booleans) or as callables (functions). The distinction is crucial: static values are evaluated once when the module loads, while callables are evaluated every time a new instance is created. This behavior is particularly important for mutable objects; using a static list or dictionary as a default will result in that same object being shared across all instances, leading to severe data bugs. Always use a callable like dict or list for these types.
For timestamp fields, understanding the difference between default, auto_now, and auto_now_add is essential. auto_now_add=True sets the field only on creation, making it immutable via the ORM save method, while auto_now=True updates the field every time the object is saved. For more control, using default=timezone.now allows the creation time to be set automatically while still remaining editable if necessary.
Code Breakdown
default='pending' sets a static string. If an Order is created without a status, it will be 'pending'.default=generate_sku passes the function itself, not the result. Django calls generate_sku() for each new order, ensuring a unique ID.default=timezone.now is the correct way to set a default timestamp. Using timezone.now() would set the default to the time when the server started, which is incorrect.dict or list. Using a literal {} would share the same dictionary instance across all models, leading to severe bugs.
