Skip to content

Models

As mentioned earlier, Django provides an abstraction layer (the "Model") for structuring and manipulating the data of your web application.

What is a Model

In Django, a model is a Python class that defines the structure of a database table and represents a data entity in your application.

  • Generally, each model maps to a single database table.
    • See TimeTrackedModel abstract model below, that doesn't create a database table.
  • Each object (or instance) of a model class represents a record (or row) in the corresponding database table.
  • Each attribute of the model class corresponds to a column/field.
  • Models can also include methods and optional metadata.
  • Django's ORM allows you to perform CRUD operations (create, read, update, delete) without writing raw SQL.

Every Django model inherits from the base class django.db.models.Model. The following example defines a Person model:

python
from django.db.models import Model, CharField, DateTimeField

class Person(Model):
    first_name = CharField(max_length=30)
    last_name = CharField(max_length=30)
    created_at = DateTimeField(auto_now_add=True)
    updated_at = DateTimeField(auto_now=True)

The above Person model would create a database table like this:

sql
CREATE TABLE myapp_person (
    "id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL,
    "created_at" timestamp with time zone NOT NULL,
    "updated_at" timestamp with time zone NOT NULL
);

Key points about this model:

  • Django automatically adds an id primary key column.
  • The first_name and last_name fields store the person's name.
  • The CREATE TABLE SQL is shown in PostgreSQL syntax, but Django generates SQL specific to the database backend configured in your settings.py file.
  • The timestamp fields track when a record is created or updated:
    • auto_now_add: Automatically sets the field to the current timestamp when the record is first created; it does not change on updates.
    • auto_now: Automatically updates the field to the current timestamp every time the record is saved; useful for "last modified" tracking.

If you want to maintain these timestamps across all models of your application, adding created_at and updated_at fields to every model can become redundant and violates the DRY (Don't Repeat Yourself) principle that Django encourages.

A better approach is to create an abstract base model that includes these fields, and then have your models inherit from it:

python
class TimeTrackedModel(Model):
    created_at = DateTimeField(auto_now_add=True)
    updated_at = DateTimeField(auto_now=True)

    class Meta:
        # This makes the model abstract, meaning no table will be created.
        abstract = True

Now, the Person model can simply inherit from TimeTrackedModel:

python
class Person(TimeTrackedModel):
    first_name = CharField(max_length=30)
    last_name = CharField(max_length=30)

Meta Options

Model Methods

Model Managers

TODO: Consider moving it to a dedicated page.

Model Inheritance

TODO: Consider moving it to a dedicated page.

Model-Specific Exceptions

See "Model Class Reference" doc - has only 2 exceptions that occur during querying.

When you define a model, Django automatically provides it with two exceptions.

DoesNotExist

MultipleObjectsReturned

Organizing models in a package

https://docs.djangoproject.com/en/5.2/topics/db/models/#organizing-models-in-a-package

Overrides

TODO: id field behavior, better table name, model methods etc.