100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

Defining Models

How to declare Django models as Python classes that map to database tables, including field types, options, and Meta configuration.

Models & ORMBeginner8 min readJul 10, 2026
Analogies

What Is a Django Model?

A Django model is a Python class that subclasses django.db.models.Model, and each attribute on the class represents a database column. Django's ORM translates the class definition into SQL DDL through migrations, so you never hand-write CREATE TABLE statements. Each model typically lives in an app's models.py file, and Django automatically adds an auto-incrementing id primary key unless you define your own.

🏏

Cricket analogy: Think of a model like a scorecard template used across every Test match — the columns for runs, balls faced, and dismissals are fixed by the format, just as a model's fields define the fixed columns every row in the database table must have.

Field Types and Options

Django ships with field classes like CharField, IntegerField, DateTimeField, and BooleanField that map directly to appropriate database column types and enforce Python-level validation before a value ever reaches the database. Field options such as max_length, null, blank, default, and unique let you tune constraints per column: null controls whether the database allows NULL, while blank controls whether Django's form validation requires a value, and the two are deliberately separate concerns.

🏏

Cricket analogy: Choosing CharField versus IntegerField is like a scorer deciding whether the 'dismissal type' column takes free text like 'caught behind' or a fixed number — the field type constrains what can legally be entered, the same way a stat sheet enforces its column formats.

python
class Book(models.Model):
    title = models.CharField(max_length=200)
    isbn = models.CharField(max_length=13, unique=True)
    published_date = models.DateField(null=True, blank=True)
    price = models.DecimalField(max_digits=6, decimal_places=2)
    is_available = models.BooleanField(default=True)

    class Meta:
        ordering = ['title']
        verbose_name = 'Book'

    def __str__(self):
        return self.title

Meta Options and String Representation

The inner Meta class configures model-wide behavior without adding a database column: ordering sets the default query order, verbose_name and verbose_name_plural control admin display text, and unique_together (or the newer UniqueConstraint in Meta.constraints) enforces multi-column uniqueness. Defining __str__ is not optional in practice — without it, every object shows up as an unhelpful 'Book object (1)' in the admin, shell, and error messages, so it should always return a human-readable identifier.

🏏

Cricket analogy: Meta.ordering set to '-runs' is like a broadcaster's graphics team always sorting the leaderboard by highest score first — every query result displaying batters follows that same default sort unless overridden.

  • A Django model subclasses models.Model and each class attribute becomes a database column.
  • Field types like CharField, IntegerField, and DateTimeField map to appropriate SQL column types and validate input.
  • null controls database-level NULL storage; blank controls form-level validation — they are independent settings.
  • Meta.ordering, verbose_name, and unique_together configure table-wide behavior without adding columns.
  • Always define __str__ so objects are readable in the admin, shell, and logs.
  • Django auto-adds an id AutoField primary key unless you explicitly define your own primary key.
  • max_digits and decimal_places on DecimalField avoid floating-point rounding errors for monetary values.

Practice what you learned

Was this page helpful?

Topics covered

#Python#DjangoStudyNotes#WebDevelopment#DefiningModels#Defining#Models#Django#Model#StudyNotes#SkillVeris