← Назад к вопросам

По какому механизму работает Django

1.8 Middle🔥 181 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Механизм работы Django

Django — это полнофункциональный веб-фреймворк, построенный по архитектурному паттерну MTV (Model-Template-View). Давайте разберёмся в его внутреннем механизме работы.

MTV архитектура Django

M — Model (модель данных) T — Template (шаблон для рендеринга HTML) V — View (обработчик логики)

Пользователь (Browser)
    ↓
URL Routing (/articles/1/)
    ↓
View (обработчик логики)
    ↓
Model (запрос к БД)
    ↓
Template (рендеринг HTML)
    ↓
HTTP Response
    ↓
Пользователь (Browser)

Жизненный цикл HTTP запроса в Django

Шаг 1: Получение запроса

# 1. WSGI сервер (Gunicorn) получает HTTP запрос
GET /articles/1/ HTTP/1.1
Host: example.com

Шаг 2: URL Routing

# urls.py — маршрутизация
from django.urls import path
from . import views

urlpatterns = [
    path('articles/<int:article_id>/', views.article_detail),
]

# Django сравнивает URL с паттернами
# /articles/1/ соответствует паттерну articles/<int:article_id>/
# Захватывает: article_id=1

Шаг 3: View обработчик

# views.py — обработчик логики
from django.shortcuts import render, get_object_or_404
from .models import Article

def article_detail(request, article_id):
    # View получает request и параметры из URL
    article = get_object_or_404(Article, id=article_id)
    
    # Может обрабатывать логику, проверять права доступа и т.д.
    if not article.is_published:
        raise PermissionDenied()
    
    # Передаёт данные в template
    return render(request, 'article_detail.html', {'article': article})

Шаг 4: Model (ORM)

# models.py — определение структуры данных
from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    is_published = models.BooleanField(default=False)
    
    def __str__(self):
        return self.title

# Django ORM преобразует queryset в SQL
article = Article.objects.get(id=1)
# Генерирует SQL: SELECT * FROM article WHERE id = 1

Шаг 5: Template рендеринг

<!-- article_detail.html -->
<html>
<body>
    <h1>{{ article.title }}</h1>
    <div>{{ article.content }}</div>
    <p>Created: {{ article.created_at|date:"Y-m-d" }}</p>
</body>
</html>

Django template engine:

  • Парсит HTML с переменными {{ variable }}
  • Подставляет значения из контекста
  • Выполняет фильтры и теги {{ variable|filter }}

Шаг 6: HTTP Response

# Django отправляет HTML обратно браузеру
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234

<html>...(rendered HTML)...</html>

Middleware система Django

Django обрабатывает запрос через серию middleware:

# settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
]

# Порядок выполнения:
# Request ↓
# SecurityMiddleware
# SessionMiddleware
# CommonMiddleware
# CsrfViewMiddleware
# AuthenticationMiddleware
# MessageMiddleware
# ↓ View
# ↑ Response
# MessageMiddleware
# CsrfViewMiddleware
# CommonMiddleware
# SessionMiddleware
# SecurityMiddleware
# ↑ Response обратно к клиенту

Пример Custom Middleware

class LoggingMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
    
    def __call__(self, request):
        # До View
        print(f"Request: {request.method} {request.path}")
        
        # View обработка
        response = self.get_response(request)
        
        # После View
        print(f"Response: {response.status_code}")
        
        return response

Django ORM механика

from django.db import models
from django.db.models import Q

class Article(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

# QuerySet — lazy evaluation
articles = Article.objects.all()
# SQL не выполнён ещё! (lazy)

# SQL выполняется только при итерации
for article in articles:  # SQL запрос выполняется ТУТ
    print(article.title)

# Или при вызове методов
articles = Article.objects.filter(published=True).order_by('-created_at')
# SQL: SELECT * FROM article WHERE published=True ORDER BY created_at DESC

# Select related (JOIN)
articles = Article.objects.select_related('author')
# SQL с JOIN: SELECT ... FROM article JOIN user ...

# Prefetch related (N+1 проблема избегается)
articles = Article.objects.prefetch_related('comments')
# Выполняет 2 запроса вместо N+1

Аутентификация и авторизация

from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User

@login_required
def user_profile(request):
    user = request.user  # Текущий пользователь
    
    if request.user.is_authenticated:
        print(f"Logged in as {user.username}")
    else:
        print("Anonymous user")
    
    return render(request, 'profile.html', {'user': user})

# Проверка прав доступа
if request.user.has_perm('can_edit_article'):
    # Разрешено
    pass

Сессии в Django

from django.contrib.sessions.models import Session

def login_view(request):
    # Сохранение данных в сессию
    request.session['user_id'] = user.id
    request.session['cart'] = ['item1', 'item2']
    
    # session_id сохраняется в cookie
    # На сервере в БД (Session таблица)

def get_user_from_session(request):
    user_id = request.session.get('user_id')
    cart = request.session.get('cart', [])
    
    return user_id, cart

Signals (события в Django)

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        # Сигнал сработает после создания User
        Profile.objects.create(user=instance)

# Есть и другие сигналы:
# pre_save, post_save, pre_delete, post_delete и т.д.

Диаграмма полного цикла

1. Client (Browser)
   ↓
2. WSGI Server (Gunicorn, uWSGI)
   ↓
3. Django WSGI Application
   ↓
4. Middleware (Request phase)
   ↓
5. URL Router
   ↓
6. View Function/Class
   ↓
7. ORM Query (Model)
   ↓
8. Database Query
   ↓
9. Template Rendering
   ↓
10. Middleware (Response phase)
   ↓
11. HTTP Response
   ↓
12. Client (Browser)

Асинхронность в Django

# Django 3.1+ поддерживает async views
from django.http import JsonResponse

async def async_view(request):
    # Асинхронная обработка
    data = await some_async_operation()
    return JsonResponse(data)

# Но Django остаётся в основном синхронным!
# Асинхронность — для IO операций (БД, API)

Заключение

Django работает по следующему механизму:

  1. WSGI сервер получает HTTP запрос
  2. Middleware предварительно обрабатывает запрос
  3. URL Router находит соответствующий View
  4. View обрабатывает логику и работает с Models
  5. ORM преобразует операции в SQL запросы
  6. Database возвращает данные
  7. Template Engine рендерит HTML
  8. Middleware постобработивает Response
  9. HTTP Response отправляется клиенту

Этот синхронный request/response цикл делает Django удобным для традиционных веб-приложений, но неэффективным для high-load и real-time систем.