SyntaxStudy
Sign Up
Django Defining Django Models and Fields
Django Beginner 1 min read

Defining Django Models and Fields

Django models are Python classes that inherit from django.db.models.Model. Each class maps to a single database table and each attribute maps to a column. Django provides a rich set of field types including CharField, TextField, IntegerField, DateTimeField, BooleanField, ForeignKey, ManyToManyField, and many others. Each field type enforces data validation at the Python level and generates the correct SQL column type for your database. Field options control behaviour: null=True allows database NULL, blank=True allows empty form values, default sets a default value, unique=True adds a uniqueness constraint, and db_index=True creates a database index. Choosing the right field type and options is critical for both data integrity and performance. For example, using db_index=True on a ForeignKey column (which Django does automatically) ensures fast lookups on related objects. After defining or changing models you must generate and apply migrations. The command python manage.py makemigrations inspects your models and creates migration files that describe the schema changes. The command python manage.py migrate applies those changes to the database. Django tracks which migrations have been applied using the django_migrations table, making schema management reproducible across environments.
Example
# blog/models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone


class Category(models.Model):
    name = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(max_length=100, unique=True)

    class Meta:
        verbose_name_plural = 'categories'
        ordering = ['name']

    def __str__(self):
        return self.name


class Post(models.Model):
    STATUS_DRAFT     = 'draft'
    STATUS_PUBLISHED = 'published'
    STATUS_CHOICES   = [
        (STATUS_DRAFT,     'Draft'),
        (STATUS_PUBLISHED, 'Published'),
    ]

    title      = models.CharField(max_length=200)
    slug       = models.SlugField(max_length=200, unique_for_date='published_at')
    author     = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
    category   = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True)
    body       = models.TextField()
    status     = models.CharField(max_length=10, choices=STATUS_CHOICES, default=STATUS_DRAFT)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    published_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        ordering = ['-published_at']
        indexes  = [models.Index(fields=['-published_at'])]

    def __str__(self):
        return self.title