Django Models

Defining database structure with Python classes

🗄️ What are Django Models?

Django models are Python classes that define your database structure. Each model represents a database table, and each attribute represents a field in that table.


# models.py
from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)
                                    

Key Model Concepts

📋

Fields

Define data types for columns

name = models.CharField()
🔑

Primary Key

Unique identifier for records

id = models.AutoField()
🔗

Relationships

Connect models together

author = models.ForeignKey()
⚙️

Methods

Add custom functionality

def __str__(self):
    return self.name

🔹 Creating Your First Model

Models are defined in the models.py file of your Django app. Each model class inherits from models.Model and defines fields that represent database columns.

# models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    pages = models.IntegerField()
    price = models.DecimalField(max_digits=6, decimal_places=2)
    
    def __str__(self):
        return self.title

After creating a model, run these commands:

python manage.py makemigrations
python manage.py migrate

🔹 Common Field Types

Django provides various field types for different data:

from django.db import models

class Example(models.Model):
    # Text fields
    name = models.CharField(max_length=100)  # Short text
    description = models.TextField()  # Long text
    
    # Number fields
    age = models.IntegerField()  # Whole numbers
    price = models.DecimalField(max_digits=10, decimal_places=2)  # Decimals
    rating = models.FloatField()  # Floating point
    
    # Date and time
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    birth_date = models.DateField()
    
    # Boolean
    is_active = models.BooleanField(default=True)
    
    # Email and URL
    email = models.EmailField()
    website = models.URLField()

🔹 Field Options

Customize field behavior with options:

class Product(models.Model):
    # Required field (default)
    name = models.CharField(max_length=100)
    
    # Optional field
    description = models.TextField(blank=True, null=True)
    
    # Field with default value
    status = models.CharField(max_length=20, default='active')
    
    # Unique field
    sku = models.CharField(max_length=50, unique=True)
    
    # Field with choices
    CATEGORY_CHOICES = [
        ('electronics', 'Electronics'),
        ('clothing', 'Clothing'),
        ('food', 'Food'),
    ]
    category = models.CharField(max_length=20, choices=CATEGORY_CHOICES)

🔹 Model Relationships

Connect models using relationship fields:

🔸 One-to-Many (ForeignKey)

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    # One author can have many books

🔸 Many-to-Many

class Student(models.Model):
    name = models.CharField(max_length=100)

class Course(models.Model):
    name = models.CharField(max_length=100)
    students = models.ManyToManyField(Student)
    # Many students can enroll in many courses

🔸 One-to-One

class User(models.Model):
    username = models.CharField(max_length=50)

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField()
    # Each user has one profile

🔹 Model Methods

Add custom methods to your models:

class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    discount = models.IntegerField(default=0)
    
    def __str__(self):
        # String representation
        return self.name
    
    def get_discounted_price(self):
        # Custom method
        return self.price - (self.price * self.discount / 100)
    
    class Meta:
        # Model metadata
        ordering = ['-price']
        verbose_name = 'Product'
        verbose_name_plural = 'Products'

🔹 Complete Model Example

A real-world blog post model with all features:

from django.db import models
from django.contrib.auth.models import User

class BlogPost(models.Model):
    STATUS_CHOICES = [
        ('draft', 'Draft'),
        ('published', 'Published'),
    ]
    
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.TextField()
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    views = models.IntegerField(default=0)
    
    def __str__(self):
        return self.title
    
    def get_absolute_url(self):
        return f'/blog/{self.slug}/'
    
    class Meta:
        ordering = ['-created_at']
        verbose_name = 'Blog Post'
        verbose_name_plural = 'Blog Posts'

🧠 Test Your Knowledge

Which field type is used for storing whole numbers?