Django Models define the structure and behavior of application data as Python classes inheriting from django.db.models.Model, where each class attribute represents a database field, and the ORM (Object-Relational Mapper) translates Python operations (create, filter, save, delete) into SQL queries against a relational database.
The Models/ORM layer solves the impedance mismatch between Python objects and relational tables. Instead of writing SQL, developers define fields (CharField, IntegerField, ForeignKey, ManyToManyField) with constraints (null, blank, unique, choices), and Django handles schema creation (migrations), query generation, and object hydration. The ORM supports relationships, aggregation, annotation, and raw SQL escape hatches.
- Model defined — Python class with field instances as class attributes
- Migration created —
makemigrationsinspects model changes, generates schema operations - Migration applied —
migrateexecutes SQL (CREATE TABLE, ALTER TABLE) on database - Query issued —
Model.objects.filter(...)returns lazyQuerySet - SQL generated — QuerySet compiles to SELECT with JOINs for relationships
- Results hydrated — Rows converted to model instances (or dicts via
.values()) - Instance saved —
instance.save()generates INSERT or UPDATE
- Field types map to SQL:
CharField→VARCHAR,IntegerField→INTEGER,DateTimeField→TIMESTAMP - Relationships:
ForeignKey(many-to-one),ManyToManyField,OneToOneFieldwithon_deletebehavior - Meta options:
db_table,ordering,indexes,constraints,unique_together,verbose_name - Managers:
objects = Manager()customizes default queryset;QuerySet.as_manager()for chainable managers - Deferred loading:
.only(),.defer()control field selection;select_related/prefetch_relatedfor JOINs
- Built from: Database Migrations — Schema sync mechanism
- Built from: Model Fields — Field type definitions
- Built from: Relationship Fields — FK, M2M, O2O
- Builds into: QuerySet API — Filter, annotate, aggregate
- Builds into: Model Managers — Custom query entry points
- Builds into: Admin Panel — Auto-registers models
- Builds into: ModelForms — Form generation from model
- Builds into: DRF Serializers —
ModelSerializer - Contrasts with: SQLAlchemy — Data Mapper pattern, explicit session, more flexible
- Contrasts with: Raw SQL — Full control, no abstraction overhead
- Related: Database Transactions —
atomic()blocks - Related: Model Signals —
pre_save,post_delete,m2m_changed
- N+1 queries: Accessing
post.author.namein loop → useselect_related('author') - M2M through table:
ManyToManyFieldcreates hidden table;through=for custom intermediate model - Default mutable:
default=[]shares list across instances; usedefault=listordefault=lambda: [] - Migration reversibility:
RunSQL/RunPythonneed reverse code; data migrations can break rollback - Abstract base classes:
abstract = Truein Meta prevents table creation; fields inherited