Django ORM Fundamentals: Model Definitions, Field Types, and Database Operations
Understanding Model Fields
Django models translate Python class definitions into data base schema structures. The framework introspects field types to determine appropriate database column types, HTML form widgets for the admin interface, and basic validation rules.
When defining models, Django automatically creates an auto-incrementing primary key named id unless explicitly overridden. Each model must contain exactly one primary key designation.
Naming Conventions:
- Follow Python identifier standards
- Avoid consecutive underscores (reserved for Django's query lookup syntax)
Import fields from django.db.models, typically aliased as models.
Core Field Types
Identifier Fields
AutoField automatically generates unique integers for primary keys. While Django creates this implicitly, explicit definition allows customization:
emp_id = models.AutoField(primary_key=True)
Character Data
CharField stores string data with a mandatory max_length parameter, mapping to VARCHAR in SQL databases. Use TextField for content exceeding 4000 characters, which renders as a textarea widget:
department = models.CharField(max_length=100, db_index=True)
biography = models.TextField(null=True, blank=True)
Numeric Types
Integer fields handle whole numbers, while DecimalField manages precise monetary values requiring max_digits (total count) and decimal_places (fractional precision):
years_experience = models.IntegerField(default=0)
salary = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
rating = models.FloatField(default=5.0)
Temporal Fields
Date and time fields accept auto_now (updates on every save) and auto_now_add (sets on creation) parameters:
hire_date = models.DateField(auto_now_add=True)
last_review = models.DateTimeField(auto_now=True)
Note: auto_now, auto_now_add, and default are mutually exclusive options.
Boolean and Binary Fields
BooleanField represents true/false states, rendering as checkboxes in forms. For important records, implement soft deletion flags rather than physical removal:
is_active = models.BooleanField(default=True)
File Handling
FileField manages uploads, while ImageField extends this with image validation (requires Pillow library):
resume = models.FileField(upload_to='documents/%Y/%m/', null=True)
avatar = models.ImageField(upload_to='profiles/', blank=True)
Field Options and Constraints
Configure field behavior through optional parameters passed during instantiation:
Database Constraints:
null=True: Allows NULL values at the database levelunique=True: Enforces column uniquenessdb_index=True: Creates database index for query optimizationdb_column='custom_name': Maps to specific database column name
Admin Interface Behavior:
blank=True: Permits empty values in forms (distinct fromnull)default=value: Specifies fallback valueeditable=False: Excludes field from admin interfaceverbose_name='Human Readable': Customizes display labels
Temporal Automation:
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
Enumerated Choices: Define tuples of value/display pairs to restrict input options:
ROLE_OPTIONS = (
(1, 'Administrator'),
(2, 'Manager'),
(3, 'Contributor'),
)
access_level = models.IntegerField(choices=ROLE_OPTIONS, default=3)
Model Metadata:
Customize table naming through inner Meta classes:
class Meta:
db_table = 'personnel_records'
Complete Implementation Example
from django.db import models
class PersonnelRecord(models.Model):
# Primary identifier
employee_code = models.AutoField(auto_created=True, primary_key=True)
# Character fields with constraints
full_name = models.CharField(max_length=50, unique=True, db_index=True)
department = models.CharField(max_length=30, default='Unassigned')
bio = models.TextField(null=True, blank=True)
# Numeric data
age = models.IntegerField(default=21)
hourly_rate = models.DecimalField(max_digits=6, decimal_places=2, default=15.00)
performance_score = models.FloatField(default=3.5)
# Status and deletion tracking
is_full_time = models.BooleanField(default=True)
is_deleted = models.BooleanField(default=False) # Soft deletion flag
# Temporal tracking
birth_date = models.DateField(default='1990-01-01')
joined_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# Media uploads
document = models.FileField(null=True, blank=True, upload_to='uploads/docs/')
profile_pic = models.ImageField(null=True, blank=True, upload_to='uploads/images/')
# Categorized selection
SKILL_LEVELS = ((1, 'Junior'), (2, 'Mid-level'), (3, 'Senior'))
expertise = models.IntegerField(
choices=SKILL_LEVELS,
default=1,
db_column='skill_tier',
verbose_name='Professional Level'
)
# Hidden admin field
internal_notes = models.IntegerField(default=0, editable=False)
class Meta:
db_table = 'employee_data'
def __str__(self):
return f"{self.employee_code}: {self.full_name} ({self.department})"
def __repr__(self):
return f"<PersonnelRecord: {self.full_name}>"
Database Migration Workflow
After modifying models, generate migration files containing schema changes:
python manage.py makemigrations
Apply migrations to synchronize the database schema:
python manage.py migrate
Important: When adding non-nullable fields to existing tables, provide default values to handle existing records.
Admin Interface Configuration
Anable model management through Django's administrative interface by registering models in admin.py. First, create a superuser account:
python manage.py createsuperuser
The __str__ method controls how records display in admin lists and dropdowns, while __repr__ aids debugging.
Rollback Procedures
To reverse migrations:
- Remove migration files from the application's
migrationsdirectory (preserve__init__.py) - Drop affected tables from the database or revert to previous migration state
- Regenerate initial migration and reapply