Django Core Concepts: Architecture, ORM, Templates, and URL Routing

Web Framework Architecture

A web framework essentially consists of a socket server that communicates with browsers. The server-side responsibilities break down into three functional areas:

  1. Message handling - exchanging data with browsers via socket communication (handled by wsgiref, uWSGI, or Gunicorn)
  2. Request routing - mapping user requests to specific handler functions
  3. Template rendering - loading HTML content and performing string substitution (typically using Jinja2)

WSGI Specification

WSGI (Web Server Gateway Interface) defines a standardized interface between web applications and web servers. This specification enables loose coupling between application code and server implementations.

Common WSGI server options:

  • uwsgi and Gunicorn - production-grade servers
  • wsgiref - Python's built-in reference implementation, used by Django's development server

ORM Operations

Querying Records

all_users = models.UserInfo.objects.all()
filtered_users = models.User.objects.filter(status='active')

Creating Records

models.UserInfo.objects.create(username="alice", email="alice@example.com")

Ordering Results

publishers = models.Publisher.objects.all().order_by("-id")  # descending

Deleting Records

# Method 1: fetch then delete
target = models.Publisher.objects.get(id=record_id)
target.delete()

# Method 2: direct deletion
models.Publisher.objects.filter(id=7).delete()

Updating Records

target_id = request.POST.get("publisher_id")
new_name = request.POST.get("publisher_name")

publisher = models.Publisher.objects.get(id=target_id)
publisher.name = new_name
publisher.save()

Database Schema Design

from django.db import models

class Publisher(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64, null=False, unique=True)
    address = models.CharField(max_length=128)
    established_date = models.DateField(auto_now_add=True)

    def __str__(self):
        return f"<Publisher: {self.name}>"

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=64, null=False, unique=True)
    publication_year = models.IntegerField(default=2023)
    publisher = models.ForeignKey(to="Publisher", on_delete=models.CASCADE)

    def __str__(self):
        return f"<Book: {self.title}>"

class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32, null=False, unique=True)
    bio = models.TextField(blank=True)
    # Many-to-many relationship managed automatically by Django ORM
    written_books = models.ManyToManyField(to="Book", related_name="authors")

    def __str__(self):
        return f"<Author: {self.name}>"

Relationship Types

Relationship Implementation Example
One-to-Many ForeignKey Book → Publisher
Many-to-Many ManyToManyField Author ↔ Book

Creating Books

# Using foreign key ID directly
models.Book.objects.create(
    title="New Title",
    publisher_id=selected_publisher_id
)

# Using related object
publisher_instance = models.Publisher.objects.get(id=selected_publisher_id)
models.Book.objects.create(
    title="Another Title",
    publisher=publisher_instance
)

Querying Many-to-Many Relationships

{% for author in author_list %}
<tr>
    <td>{{ forloop.counter }}</td>
    <td>{{ author.id }}</td>
    <td>{{ author.name }}</td>
    <td>
        {% for book in author.written_books.all %}
            <span>{{ book.title }}</span>
        {% endfor %}
    </td>
</tr>
{% endfor %}

Custom Template Filters

Template filters are functions that accept one or two parameters. In {{ variable|filter_name:argument }}, the filter receives variable and argument.

Project Structure

myapp/
    __init__.py
    models.py
    templatetags/
        __init__.py
        custom_filters.py
    views.py

Defining Filters

from django import template

register = template.Library()

@register.filter(name="truncate_wrapped")
def truncate_wrapped(text):
    """Wraps text with suffix"""
    return f"{text} [filtered]"

@register.filter(name="greet")
def greet_user(name, greeting):
    """
    First parameter: value before the pipe operator
    Second parameter: value after the colon
    """
    return f"{greeting}, {name}!"

Using Filters in Templates

{% load custom_filters %}

{{ username|truncate_wrapped }}
{{ username|greet:"Hello" }}

Custom Simple Tags

Simple tags offer more flexibility than filters, accepting multiple parameters.

Definition

@register.simple_tag(name="calculate")
def calculate_sum(a, b, c):
    return f"{a} + {b} + {c} = {a + b + c}"

Usage

{% load custom_filters %}
{% calculate 10 20 30 %}

Inclusion Tags

Inclusion tags render HTML fragments, useful for reusable components.

Definition

@register.inclusion_tag('components/list_items.html')
def render_list(count):
    count = max(1, int(count))
    items = [f"Item #{i}" for i in range(1, count + 1)]
    return {"items": items}

Template (components/list_items.html)

<ul>
{% for item in items %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

Usage

{% load custom_filters %}
{% render_list 5 %}

Class-Based Views

from django.views import View

class PublisherCreate(View):
    def get(self, request):
        return render(request, 'create_publisher.html')
    
    def post(self, request):
        name = request.POST.get('name')
        models.Publisher.objects.create(name=name)
        return redirect('/publishers')

URL Reverse Resolution

Named URL patterns enable dynamic URL generation, decoupling templates and views from hardcoded paths.

Defining Named Routes

urlpatterns = [
    url(r'^publishers/$', views.publisher_list, name='publisher_list'),
    url(r'^publishers/(?P<pk>\d+)/$', views.publisher_detail, name='publisher_detail'),
]

In Templates

<a href="{% url 'publisher_list' %}">All Publishers</a>
<a href="{% url 'publisher_detail' publisher.id %}">View Details</a>

In Views

from django.urls import reverse

# Without parameters
list_url = reverse('publisher_list')

# With positional arguments
detail_url = reverse('publisher_detail', args=(42,))

# With keyword arguments
detail_url = reverse('publisher_detail', kwargs={'pk': 42})

URL Routing Patterns

Positional Regex Groups

url(r'^books/([0-9]{4})/([a-z]+)/$', views.book_detail, name='book_detail'),
# Captures: year, category

Named Regex Groups

url(r'^books/(?P<year>[0-9]{4})/(?P<category>[a-z]+)/$', 
    views.book_detail, 
    name='book_detail'),
# Captures: year, category as keyword arguments

ORM Field Reference

Common Field Types

class ExampleModel(models.Model):
    # Auto-incrementing primary key
    id = models.AutoField(primary_key=True)
    
    # Variable-length string
    name = models.CharField(max_length=100)
    
    # Foreign key relationship
    category = models.ForeignKey(
        to='Category',
        on_delete=models.CASCADE,
        related_name='items'
    )
    
    # Many-to-many relationship
    tags = models.ManyToManyField(to='Tag')
    
    # Date and time fields
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    event_date = models.DateField()
    event_time = models.TimeField()
    
    # Numeric fields
    quantity = models.IntegerField(default=0)
    price = models.DecimalField(max_digits=10, decimal_places=2)

Field Parameters

Parameter Purpose Example
null Allow NULL in database null=True
blank Allow empty in forms blank=True
default Default value default='pending'
unique Enforce uniqueness unique=True
db_index Create database index db_index=True
choices Limit to predefined values choices=STATUS_CHOICES

Meta Options

class Meta:
    db_table = 'custom_table_name'
    ordering = ['-created_at']
    verbose_name = 'Custom Name'
    verbose_name_plural = 'Custom Names'

CRUD Operations Summary

Single Table Operations

# Create
publisher = models.Publisher.objects.create(name="New Publisher")

# Read
publisher = models.Publisher.objects.get(id=1)
all_publishers = models.Publisher.objects.all()

# Update
publisher = models.Publisher.objects.get(id=1)
publisher.name = "Updated Name"
publisher.save()

# Delete
models.Publisher.objects.get(id=1).delete()

Foreign Key Access

book = models.Book.objects.get(id=1)

# Access related object
book.publisher.name

# Access foreign key value directly
book.publisher_id

# Set relationship
book.publisher = new_publisher
book.save()

Many-to-Many Operations

author = models.Author.objects.get(id=1)

# Get all books by author
author.written_books.all()

# Set multiple books
author.written_books.set([book1, book2, book3])

# Add single book
author.written_books.add(book4)

# Remove book
author.written_books.remove(book4)

# Clear all relationships
author.written_books.clear()

DateTime Utilities

import datetime

current_time = datetime.datetime.now()
print(f"Now: {current_time}")

# Time delta calculations
one_day = datetime.timedelta(days=1)
one_week = datetime.timedelta(weeks=1)
expiry_date = current_time + datetime.timedelta(days=7)

# Date formatting
formatted = current_time.strftime("%Y-%m-%d %H:%M:%S")

Running Django Outside Management Script

#!/usr/bin/env python
import os
import sys

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project_name.settings")
    import django
    django.setup()
    
    from myapp import models
    
    # Now you can use ORM here
    all_books = models.Book.objects.select_related('publisher').all()
    for book in all_books:
        print(f"{book.title} - {book.publisher.name}")

Tags: Django python web development ORM Template Tags

Posted on Sun, 25 Oct 2026 16:24:17 +0000 by erupt