Django Architecture & ORM
Django is the world's leading high-level Python web framework, designed to help developers build secure, scalable applications in hours instead of months.
The "Batteries-Included" Concept:
Unlike Flask where you must manually choose and configure dozens of third-party libraries for databases, authentication, admin interfaces, and migrations, Django bundles all of them into the core framework with unified, battle-tested security standards.
The MTV (Model-Template-View) Architecture:
While traditional frameworks refer to MVC (Model-View-Controller), Django uses the MTV terminology:
- Model (M): The data layer (Python classes defining database tables and business logic via Django ORM).
- Template (T): The presentation layer (HTML files rendered with the Django Template Language / DTL).
- View (V): The controller/logic layer (Python functions or classes that process requests, query Models, and return Templates or JSON).
# Django Project Structure Overview (Created via django-admin startproject):
"""
my_ecommerce_project/
โโโ manage.py <-- CLI utility for running server, migrations, tests
โโโ my_ecommerce_project/ <-- Project root configuration package
โ โโโ __init__.py
โ โโโ settings.py <-- Central configuration (DB, installed apps, middleware)
โ โโโ urls.py <-- Master URL routing dispatcher
โ โโโ asgi.py <-- Asynchronous server entry point
โ โโโ wsgi.py <-- WSGI production deployment entry point
โโโ store_app/ <-- Modular Django Application (python manage.py startapp store_app)
โโโ models.py <-- Database ORM Models
โโโ views.py <-- Request Handler Views
โโโ urls.py <-- App-specific URL routes
โโโ admin.py <-- Admin Dashboard Configuration
โโโ migrations/ <-- Version-controlled DB schema migration scripts
"""
print("Django Project vs App Modular Architecture Loaded.")
A Project is the entire website configuration (settings, database connection, URLs). An App is a self-contained, reusable module (e.g. blog_app, payment_app, user_auth_app) that can be plugged into multiple different Django projects.
In Django, you define your database schema as Python classes inheriting from models.Model. Django ORM handles table creation, column types, validations, and SQL generation.
The 2-Step Migrations Lifecycle:
python manage.py makemigrations: Scans yourmodels.pyfiles, detects any added/changed/deleted fields, and writes a version-controlled migration blueprint script inmigrations/0001_initial.py.python manage.py migrate: Executes the pending migration blueprints and updates the physical SQL tables on PostgreSQL/MySQL/SQLite.
# 1. Defining Models: store_app/models.py
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=50, unique=True)
slug = models.SlugField(max_length=50, unique=True)
class Meta:
verbose_name_plural = "Categories"
def __str__(self):
return self.name
class Product(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="products")
title = models.CharField(max_length=150)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField(default=0)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.title} (โน{self.price})"
# 2. Registering with Admin: store_app/admin.py
from django.contrib import admin
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ("title", "category", "price", "stock", "is_active")
list_filter = ("is_active", "category")
search_fields = ("title", "description")
list_editable = ("price", "stock", "is_active")
By writing just 8 lines in admin.py, Django automatically generates a complete web admin interface with search bars, filters, pagination, and bulk editing capabilities!
Never manually add or alter columns directly in your SQL database when using Django! Doing so causes Django's internal django_migrations history table to fall out of sync, causing future "makemigrations" and "migrate" commands to fail.
Simulate a Django ORM query: Write a Python list filter to get all active products in the "Electronics" category with price < 5000.
products = [
{"title": "Earphones", "cat": "Electronics", "price": 1499.0, "is_active": True},
{"title": "Laptop", "cat": "Electronics", "price": 65000.0, "is_active": True},
{"title": "Desk Lamp", "cat": "Furniture", "price": 899.0, "is_active": True},
{"title": "USB Cable", "cat": "Electronics", "price": 299.0, "is_active": False}
]
# Django ORM equivalent: Product.objects.filter(is_active=True, category__name="Electronics", price__lt=5000)
matched = [p for p in products if p["is_active"] and p["cat"] == "Electronics" and p["price"] < 5000]
print("Matched Products:", matched)
Q What does on_delete=models.CASCADE do in Django ForeignKeys?
models.CASCADE specifies that if a parent record is deleted (e.g. Category), all related child records (all Products in that category) are automatically deleted from the database. Other options include models.PROTECT and models.SET_NULL.
Q How do I create a superuser for the Django admin panel?
Run "python manage.py createsuperuser" in your terminal and follow the interactive prompts to enter a username, email, and secure password.
Q What is the purpose of the __str__() method in Django models?
The __str__() method defines the human-readable string representation of a model instance displayed in the Django Admin portal, dropdown menus, and console logs.