Обзор архитектуры Django и её компонентов
Django – это высокоуровневый Python веб-фреймворк, который поощряет быструю разработку и чистый, прагматичный дизайн. Его архитектура основана на паттерне Model-View-Template (MVT), который слегка отличается от Model-View-Controller (MVC), но преследует те же цели: разделение логики приложения, данных и представления.
Основные компоненты Django включают:
- Models: Определяют структуру данных и методы доступа к ним. Используются для взаимодействия с базой данных посредством ORM (Object-Relational Mapper).
- Views: Содержат логику обработки запросов и возвращают HTTP-ответы. Views могут взаимодействовать с моделями для получения или изменения данных.
- Templates: Определяют структуру и внешний вид HTML-страниц. Используются для динамической генерации контента на основе данных, переданных из views.
- URLconf (URL configuration): Определяет соответствие между URL-адресами и views.
- Middleware: Предоставляет механизм для обработки запросов и ответов на промежуточных этапах.
- Forms: Позволяют создавать и обрабатывать HTML-формы, упрощая валидацию данных.
- Serializers: Используются для преобразования данных между форматами, например, из моделей Django в JSON и обратно (обычно применяется для API).
Роль WSGI сервера в обработке HTTP запросов
Web Server Gateway Interface (WSGI) — это стандартный интерфейс между веб-серверами (например, Apache, Nginx) и веб-приложениями (например, Django). WSGI сервер получает HTTP-запрос от клиента, передаёт его в Django, а затем получает HTTP-ответ от Django и отправляет его обратно клиенту. WSGI сервер обеспечивает низкоуровневую обработку запросов, а Django занимается логикой приложения.
Краткое описание жизненного цикла запроса в Django
Жизненный цикл запроса в Django можно представить следующим образом:
- Клиент отправляет HTTP-запрос на сервер.
- WSGI сервер получает запрос и передает его в Django.
- Middleware Django обрабатывает запрос (например, добавляет сессии, проверяет аутентификацию).
- URLconf определяет, какое view должно обработать запрос.
- View обрабатывает запрос, взаимодействует с моделями (если необходимо), и формирует HTTP-ответ.
- Middleware Django обрабатывает ответ (например, добавляет заголовки).
- WSGI сервер отправляет ответ клиенту.
Подробный разбор обработки HTTP-запроса
Получение запроса WSGI сервером и передача в Django
Когда веб-сервер получает HTTP-запрос, он передает его WSGI-серверу. WSGI-сервер (например, Gunicorn, uWSGI) действует как мост между веб-сервером и вашим Django-приложением. Он преобразует запрос в формат, понятный для Django, и передаёт его в приложение. Важно отметить, что WSGI сервер отвечает за обработку concurrency и обеспечивает стабильную работу веб-приложения.
Обработка запроса middleware Django
Middleware – это набор функций, которые обрабатывают запрос до того, как он достигнет view, и ответ после того, как он был сгенерирован view. Middleware выполняет различные задачи, такие как:
- Обработка сессий.
- Аутентификация пользователей.
- CSRF-защита.
- Обработка исключений.
- Локализация.
Пример middleware:
from typing import Callable
from django.http import HttpRequest, HttpResponse
class SimpleMiddleware:
def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]):
self.get_response = get_response
def __call__(self, request: HttpRequest) -> HttpResponse:
# Код, который выполняется перед view
print("Перед view")
response = self.get_response(request)
# Код, который выполняется после view
print("После view")
return response
Определение URL-маршрута с помощью URLconf
URLconf – это файл (обычно urls.py), который содержит список URL-шаблонов и соответствующих им views. Когда Django получает запрос, он сопоставляет URL-адрес запроса с одним из URL-шаблонов в URLconf. Если совпадение найдено, Django вызывает соответствующее view. Пример URLconf:
from django.urls import path
from . import views
urlpatterns = [
path('articles/<int:year>/', views.year_archive, name='year_archive'),
path('articles/<int:year>/<int:month>/', views.month_archive, name='month_archive'),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail, name='article_detail'),
]
В этом примере определены три URL-шаблона, которые соответствуют архиву статей по году, месяцу и детальной статье. name используется для обратного разрешения URL (например, при генерации ссылок в шаблонах).
Вызов соответствующего представления (view)
После того, как URLconf определил, какое view должно обработать запрос, Django вызывает это view. View – это функция, которая принимает объект HttpRequest в качестве аргумента и возвращает объект HttpResponse. View содержит логику обработки запроса, взаимодействия с моделями и рендеринга шаблонов.
Работа с данными в представлении (view)
Обработка данных запроса (GET, POST и другие)
View имеет доступ к данным запроса через объект HttpRequest. Данные GET-запроса доступны через request.GET, данные POST-запроса – через request.POST. Также доступны другие атрибуты, такие как request.COOKIES, request.FILES, request.META.
from django.http import HttpRequest, HttpResponse
def my_view(request: HttpRequest) -> HttpResponse:
if request.method == 'POST':
# Обработка данных из POST-запроса
form_data = request.POST
name = form_data.get('name')
# ...
return HttpResponse("Данные успешно обработаны")
elif request.method == 'GET':
# Обработка данных из GET-запроса
query_params = request.GET
search_term = query_params.get('q')
#...
return HttpResponse("Результаты поиска")
else:
return HttpResponse("Недопустимый метод")
Взаимодействие с моделями Django (ORM)
Django ORM позволяет взаимодействовать с базой данных, используя Python-код, а не SQL-запросы. Вы можете определять модели, которые соответствуют таблицам в базе данных, и использовать ORM для создания, чтения, обновления и удаления данных.
from django.shortcuts import render
from .models import Article
from django.http import HttpRequest, HttpResponse
def article_list(request: HttpRequest) -> HttpResponse:
articles = Article.objects.all() # Получение всех статей из базы данных
return render(request, 'articles/article_list.html', {'articles': articles})
Рендеринг шаблонов и формирование HTTP-ответа
После обработки данных view должен сформировать HTTP-ответ. Обычно это делается с помощью рендеринга шаблонов. Django использует шаблонизатор Django Template Language (DTL) для динамической генерации HTML-страниц. View передает данные в шаблон, который заполняет их в предопределенной структуре.
from django.shortcuts import render
from django.http import HttpRequest, HttpResponse
def my_view(request: HttpRequest) -> HttpResponse:
context = {
'name': 'John Doe',
'age': 30
}
return render(request, 'my_template.html', context)
В шаблоне my_template.html можно использовать переменные из контекста:
<p>Имя: {{ name }}</p>
<p>Возраст: {{ age }}</p>
Формирование и отправка HTTP-ответа
Обработка ответа middleware Django
После того, как view сформировал HTTP-ответ, middleware Django обрабатывает его. Middleware может добавлять заголовки, изменять контент ответа, выполнять логирование и другие задачи.
Отправка ответа WSGI серверу
После обработки middleware, Django передает HTTP-ответ WSGI серверу. WSGI сервер преобразует ответ в формат, понятный для веб-сервера, и отправляет его обратно клиенту.
Возвращение ответа клиенту
Веб-сервер получает HTTP-ответ от WSGI сервера и отправляет его обратно клиенту (например, веб-браузеру). Клиент отображает ответ, и пользователь видит результат своей работы.
Наглядная диаграмма обработки запроса в Django
graph LR
A[Клиент (браузер)] -- HTTP Запрос --> B(Веб-сервер (Nginx, Apache))
B -- WSGI Запрос --> C(WSGI сервер (Gunicorn, uWSGI))
C -- Запрос --> D{Django Middleware}
D -- Запрос --> E{URLconf}
E -- Соответствие URL --> F[View (Представление)]
F -- Взаимодействие с моделями (ORM) --> G(База данных)
F -- Данные --> H[Шаблоны]
H -- Сгенерированный HTML --> F
F -- HTTP Ответ --> D
D -- Ответ --> C
C -- WSGI Ответ --> B
B -- HTTP Ответ --> A
style A fill:#f9f,stroke:#333,stroke-width:2px
style B fill:#ccf,stroke:#333,stroke-width:2px
style C fill:#ccf,stroke:#333,stroke-width:2px
style D fill:#ffc,stroke:#333,stroke-width:2px
style E fill:#ffc,stroke:#333,stroke-width:2px
style F fill:#cfc,stroke:#333,stroke-width:2px
style G fill:#ccf,stroke:#333,stroke-width:2px
style H fill:#ccf,stroke:#333,stroke-width:2px
Описание блоков диаграммы: запрос, middleware, URLconf, view, response
- Клиент (браузер): Отправляет HTTP-запрос на сервер.
- Веб-сервер (Nginx, Apache): Принимает HTTP-запрос и передает его WSGI-серверу.
- WSGI сервер (Gunicorn, uWSGI): Преобразует HTTP-запрос в WSGI-запрос и передает его Django.
- Django Middleware: Набор функций, которые обрабатывают запрос и ответ на промежуточных этапах.
- URLconf: Определяет соответствие между URL-адресами и views.
- View (Представление): Обрабатывает запрос, взаимодействует с моделями и рендерит шаблоны.
- База данных: Хранит данные приложения.
- Шаблоны: Определяют структуру и внешний вид HTML-страниц.
- HTTP Ответ: Ответ, сформированный view и обработанный middleware, отправляется клиенту.
Пошаговое прохождение запроса по диаграмме
- Клиент отправляет запрос.
- Веб-сервер получает запрос и передает его WSGI-серверу.
- WSGI-сервер передает запрос в Django.
- Middleware Django обрабатывает запрос.
- URLconf определяет, какое view должно обработать запрос.
- View обрабатывает запрос, взаимодействует с моделями и рендерит шаблоны.
- Middleware Django обрабатывает ответ.
- WSGI-сервер передает ответ веб-серверу.
- Веб-сервер отправляет ответ клиенту.
Примеры сценариев обработки запросов
-
Запрос страницы со списком товаров:
- Клиент запрашивает URL
/products/. - URLconf сопоставляет этот URL с view
product_list. - View
product_listзапрашивает список товаров из базы данных. - View
product_listрендерит шаблонproduct_list.html, передавая в него список товаров. - Шаблон генерирует HTML-код страницы со списком товаров.
- Страница отправляется клиенту.
- Клиент запрашивает URL
-
Отправка формы заказа:
- Клиент заполняет форму заказа и отправляет POST-запрос на URL
/order/. - URLconf сопоставляет этот URL с view
create_order. - View
create_orderполучает данные из POST-запроса. - View
create_orderвалидирует данные и создает новый заказ в базе данных. - View
create_orderперенаправляет клиента на страницу подтверждения заказа.
- Клиент заполняет форму заказа и отправляет POST-запрос на URL