Перейти к основному содержимому

5.02. Справочник по Django

Разработчику Архитектору

Справочник по Django

1. Структура проекта Django

Проект Django состоит из следующих основных компонентов:

  • manage.py — скрипт командной строки для взаимодействия с проектом (запуск сервера, миграции, создание суперпользователя и т.д.).
  • settings.py — центральный файл конфигурации проекта.
  • urls.py — корневой файл маршрутизации запросов.
  • wsgi.py — точка входа для WSGI-совместимых веб-серверов.
  • asgi.py — точка входа для ASGI-совместимых серверов (для асинхронных приложений).
  • apps/ — директории приложений, каждая из которых содержит:
    • models.py — определения моделей данных.
    • views.py — логика обработки HTTP-запросов.
    • urls.py — маршруты, специфичные для приложения.
    • admin.py — регистрация моделей в админке.
    • forms.py — определения пользовательских форм.
    • tests.py или tests/ — модульные и интеграционные тесты.
    • migrations/ — автоматически генерируемые файлы миграций базы данных.
    • static/ — статические файлы (CSS, JS, изображения).
    • templates/ — HTML-шаблоны.

2. Настройки (settings.py)

Файл settings.py содержит параметры, управляющие поведением проекта. Все настройки являются переменными верхнего регистра.

Основные настройки

  • BASE_DIR — путь к корню проекта (Path(__file__).resolve().parent.parent).
  • SECRET_KEY — секретный ключ, используемый для криптографических подписей. Обязателен для работы.
  • DEBUG — режим отладки. При значении True отображаются подробные ошибки. В продакшене должен быть False.
  • ALLOWED_HOSTS — список доменов или IP-адресов, которые могут обслуживать приложение. Пример: ['example.com', '192.168.1.1'].
  • INSTALLED_APPS — список установленных приложений. Может включать:
    • встроенные приложения Django ('django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles');
    • сторонние приложения;
    • собственные приложения проекта.
  • MIDDLEWARE — список промежуточных слоёв, обрабатывающих запросы и ответы. Порядок важен. Стандартные 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'
    • 'django.middleware.clickjacking.XFrameOptionsMiddleware'

База данных

  • DATABASES — словарь конфигураций баз данных. По умолчанию используется SQLite:

    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': BASE_DIR / 'db.sqlite3',
    }
    }

    Другие поддерживаемые движки:

    • 'django.db.backends.postgresql'
    • 'django.db.backends.mysql'
    • 'django.db.backends.oracle'

    Дополнительные параметры:

    • USER — имя пользователя БД.
    • PASSWORD — пароль.
    • HOST — хост (например, 'localhost').
    • PORT — порт (например, '5432' для PostgreSQL).
    • OPTIONS — дополнительные параметры подключения (например, SSL-настройки).
    • CONN_MAX_AGE — время жизни соединения в секундах (для пула соединений).

Локализация и интернационализация

  • LANGUAGE_CODE — код языка по умолчанию ('en-us', 'ru-ru').
  • TIME_ZONE — часовой пояс ('UTC', 'Europe/Moscow').
  • USE_I18N — активация интернационализации (True/False).
  • USE_TZ — использование временных зон (True/False).

Статические файлы и медиа

  • STATIC_URL — URL-префикс для статических файлов ('/static/').
  • STATICFILES_DIRS — список дополнительных директорий для сбора статики:
    STATICFILES_DIRS = [BASE_DIR / "static"]
  • STATIC_ROOT — директория, куда собираются все статические файлы командой collectstatic.
  • MEDIA_URL — URL-префикс для медиафайлов ('/media/').
  • MEDIA_ROOT — путь к директории, где хранятся загруженные файлы (BASE_DIR / 'media').

Безопасность

  • SECURE_HSTS_SECONDS — включение HTTP Strict Transport Security (в секундах).
  • SECURE_SSL_REDIRECT — принудительное перенаправление на HTTPS.
  • SESSION_COOKIE_SECURE — отправка cookie только по HTTPS.
  • CSRF_COOKIE_SECURE — защита CSRF-токена через HTTPS.
  • SECURE_BROWSER_XSS_FILTER — включение XSS-фильтра браузера.
  • SECURE_CONTENT_TYPE_NOSNIFF — запрет MIME-sniffing.

Аутентификация

  • AUTH_USER_MODEL — кастомная модель пользователя (по умолчанию 'auth.User').
  • LOGIN_URL — URL для перенаправления неавторизованных пользователей.
  • LOGOUT_REDIRECT_URL — URL после выхода.
  • LOGIN_REDIRECT_URL — URL после входа.

Кэширование

  • CACHES — конфигурация кэша:
    CACHES = {
    'default': {
    'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    }
    }
    Поддерживаемые бэкенды:
    • 'django.core.cache.backends.locmem.LocMemCache'
    • 'django.core.cache.backends.filebased.FileBasedCache'
    • 'django.core.cache.backends.memcached.PyMemcacheCache'
    • 'django.core.cache.backends.redis.RedisCache'

Почта

  • EMAIL_BACKEND — бэкенд отправки почты:
    • 'django.core.mail.backends.smtp.EmailBackend'
    • 'django.core.mail.backends.console.EmailBackend' (для разработки)
  • EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, EMAIL_USE_TLS, EMAIL_USE_SSL — параметры SMTP.

Логирование

  • LOGGING — словарь конфигурации логгера (форматы, обработчики, уровни, логгеры).

3. Модели (models.py)

Модели описывают структуру данных и взаимодействие с базой данных.

Базовые поля

Каждое поле модели — экземпляр класса Field. Основные типы:

  • CharField(max_length=...) — строка ограниченной длины.
  • TextField() — длинный текст.
  • IntegerField(), BigIntegerField(), SmallIntegerField(), PositiveIntegerField(), PositiveSmallIntegerField() — целые числа разных диапазонов.
  • FloatField(), DecimalField(max_digits=..., decimal_places=...) — числа с плавающей точкой.
  • BooleanField() — логическое значение.
  • DateField(), DateTimeField(), TimeField() — дата и время.
    • Параметры: auto_now=True (обновляется при каждом сохранении), auto_now_add=True (устанавливается при создании).
  • EmailField() — проверка email-формата.
  • URLField() — проверка URL.
  • FileField(upload_to=...) — загрузка файла.
  • ImageField(upload_to=...) — загрузка изображения (требует Pillow).
  • ForeignKey(to, on_delete=...) — связь «многие к одному».
  • OneToOneField(to, on_delete=...) — связь «один к одному».
  • ManyToManyField(to) — связь «многие ко многим».

Параметры полей

  • null=True — разрешает NULL в БД.
  • blank=True — разрешает пустое значение в формах.
  • default=value — значение по умолчанию.
  • unique=True — уникальность значения.
  • choices=[(value, label), ...] — предопределённые варианты выбора.
  • help_text="..." — подсказка в формах.
  • verbose_name="..." — человекочитаемое имя поля.

Мета-класс (Meta)

Внутри модели можно определить вложенный класс Meta:

  • db_table = "custom_name" — имя таблицы в БД.
  • ordering = ["field"] — порядок по умолчанию.
  • verbose_name = "...", verbose_name_plural = "..." — отображаемые имена.
  • unique_together = [("field1", "field2")] — составной уникальный ключ.
  • indexes = [models.Index(fields=["field"]), ...] — индексы.
  • constraints = [models.CheckConstraint(...), ...] — ограничения уровня БД.

Методы модели

  • str(self) — строковое представление объекта.
  • get_absolute_url() — канонический URL объекта.
  • save() — переопределение логики сохранения.
  • delete() — переопределение удаления.

4. Представления (views.py)

Представления — это функции или классы, которые принимают HTTP-запрос и возвращают HTTP-ответ. Они реализуют логику приложения.

Типы представлений

Функциональные представления (Function-Based Views, FBV)

Пример:

from django.http import HttpResponse
from django.shortcuts import render

def home(request):
return render(request, 'home.html', {'title': 'Главная'})

Доступные утилиты из django.shortcuts:

  • render(request, template_name, context) — рендерит шаблон и возвращает HttpResponse.
  • redirect(to, *args, **kwargs) — перенаправляет на другой URL.
  • get_object_or_404(model, **kwargs) — возвращает объект или вызывает 404.
  • get_list_or_404(queryset) — возвращает список или вызывает 404.

Классовые представления (Class-Based Views, CBV)

Стандартные CBV из django.views.generic:

  • TemplateView — рендерит шаблон.

    from django.views.generic import TemplateView
    class AboutView(TemplateView):
    template_name = "about.html"
  • ListView — отображает список объектов.

    • model = MyModel
    • template_name = "list.html"
    • context_object_name = "items" — имя переменной в шаблоне.
    • paginate_by = 10 — пагинация.
  • DetailView — отображает один объект.

    • model = MyModel
    • template_name = "detail.html"
    • По умолчанию ожидает параметр pk или slug в URL.
  • CreateView, UpdateView, DeleteView — операции CRUD.

    • model, fields, form_class, success_url — основные параметры.
    • get_success_url() — метод для динамического определения URL после успешного действия.
  • FormView — обработка произвольной формы без привязки к модели.

Асинхронные представления

Начиная с Django 3.1, поддерживаются асинхронные представления:

async def async_view(request):
data = await fetch_data_from_api()
return render(request, 'async.html', {'data': data})

Асинхронные CBV также доступны через AsyncView и производные.


5. Маршрутизация (URLconf)

Маршрутизация связывает URL-адреса с представлениями.

Основные элементы

  • urlpatterns — список маршрутов в urls.py.

  • path(route, view, kwargs=None, name=None) — современный способ определения маршрута.

    • route — строка пути (например, 'articles/<int:id>/').
    • view — функция или результат as_view().
    • name — имя маршрута для обратного разрешения (reverse() или {% url %}).
  • re_path(route, view, kwargs=None, name=None) — маршрут с регулярным выражением (устаревший, но иногда необходим).

Параметры маршрутов

  • <int:id> — целое число.
  • <str:slug> — строка (не содержит /).
  • <slug:slug> — slug (латиница, цифры, дефис, подчёркивание).
  • <uuid:token> — UUID.
  • <path:url> — любой путь, включая /.

Включение приложений

Корневой urls.py подключает маршруты приложений:

from django.urls import include, path

urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
]

Внутри blog/urls.py:

from django.urls import path
from . import views

urlpatterns = [
path('', views.post_list, name='post_list'),
path('<int:pk>/', views.post_detail, name='post_detail'),
]

Обратное разрешение URL

  • В Python: reverse('post_detail', args=[123])
  • В шаблонах: {% url 'post_detail' pk=123 %}

6. Шаблоны (templates)

Шаблоны — это HTML-файлы с встроенными тегами и переменными Django.

Структура шаблонов

  • Базовый шаблон (base.html) содержит общую структуру:

    <!DOCTYPE html>
    <html>
    <head>
    <title>{% block title %}Сайт{% endblock %}</title>
    </head>
    <body>
    {% block content %}{% endblock %}
    </body>
    </html>
  • Дочерние шаблоны наследуют базовый:

    {% extends "base.html" %}
    {% block title %}Главная{% endblock %}
    {% block content %}
    <h1>Добро пожаловать!</h1>
    {% endblock %}

Переменные

  • {{ variable }} — вывод значения.
  • {{ object.attribute }} — доступ к атрибуту.
  • {{ dict.key }} — доступ к ключу словаря.
  • {{ list.0 }} — первый элемент списка.

Фильтры

Изменяют значение переменной:

  • {{ name|upper }}
  • {{ date|date:"d.m.Y" }}
  • {{ text|truncatewords:15 }}
  • {{ list|length }}
  • {{ value|default:"Нет данных" }}

Теги

  • {% for item in items %}...{% endfor %}
  • {% if condition %}...{% elif %}...{% else %}...{% endif %}
  • {% include "partial.html" %}
  • {% csrf_token %} — обязательный токен для форм.
  • {% load static %} — загрузка статических файлов.
  • {% url 'name' arg %} — генерация URL.

Контекст шаблона

Передаётся как словарь из представления. Автоматически добавляются:

  • user — текущий пользователь.
  • request — объект запроса (если включён RequestContext).
  • messages — сообщения Django.

7. Формы (forms.py)

Формы обеспечивают валидацию и рендеринг пользовательского ввода.

Типы форм

Обычные формы (Form)

from django import forms

class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)

Модельные формы (ModelForm)

Автоматически создаются на основе модели:

class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'author']
# или fields = '__all__'
# exclude = ['created_at']

Поля формы

Соответствуют полям модели, но с префиксом forms.:

  • CharField, EmailField, URLField, IntegerField, BooleanField, DateField, DateTimeField, ChoiceField, FileField, ImageField и др.

Виджеты (widgets)

Определяют HTML-представление поля:

  • TextInput, Textarea, EmailInput, NumberInput, DateInput, CheckboxInput, Select, FileInput, ClearableFileInput.

Пример:

message = forms.CharField(widget=forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}))

Валидация

  • clean_<field>() — валидация конкретного поля.
  • clean() — валидация всей формы.
  • raise forms.ValidationError("Ошибка") — генерация ошибки.

Обработка в представлении

def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# обработка данных: form.cleaned_data
return redirect('success')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})

Рендеринг в шаблоне

<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Отправить</button>
</form>

Альтернативы:

  • {{ form.as_table }}
  • {{ form.as_ul }}
  • Ручной рендеринг: {{ form.name.label_tag }} {{ form.name }}

8. Административная панель (admin.py)

Админка — встроенная система управления данными, автоматически генерируемая на основе моделей.

Регистрация модели

from django.contrib import admin
from .models import Article

admin.site.register(Article)

Настройка отображения

Создание кастомного класса ModelAdmin:

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'created_at')
list_filter = ('created_at', 'author')
search_fields = ('title', 'content')
prepopulated_fields = {'slug': ('title',)}
date_hierarchy = 'created_at'
ordering = ('-created_at',)
fields = ('title', 'slug', 'content', 'author')
readonly_fields = ('created_at',)
autocomplete_fields = ('author',)

Дополнительные возможности

  • list_editable — редактирование полей прямо в списке.
  • actions — массовые действия (например, публикация выбранных статей).
  • inlines — встраивание связанных объектов (например, комментариев под статьёй).
  • get_queryset() — ограничение видимых записей (например, только свои).
  • has_add_permission(), has_change_permission(), has_delete_permission() — управление правами.

9. Миграции (migrations)

Миграции — это способ синхронизации изменений в моделях с базой данных.

Основные команды

  • python manage.py makemigrations — создаёт новые миграции на основе изменений в models.py.
  • python manage.py migrate — применяет миграции к БД.
  • python manage.py showmigrations — показывает статус всех миграций.
  • python manage.py sqlmigrate app_name 0001 — отображает SQL-код миграции.
  • python manage.py migrate --fake — помечает миграцию как применённую без выполнения SQL.
  • python manage.py migrate --fake-initial — обход для существующих таблиц.

Типы миграций

  • Initial — первая миграция приложения.
  • Data migrations — миграции с пользовательским кодом (например, заполнение данных).
  • Squashed migrations — объединение нескольких миграций в одну для ускорения.

Ручное создание миграции

from django.db import migrations

def populate_data(apps, schema_editor):
Article = apps.get_model('blog', 'Article')
Article.objects.create(title="Пример", content="...")

class Migration(migrations.Migration):
dependencies = [('blog', '0001_initial')]
operations = [migrations.RunPython(populate_data)]

10. Сигналы (signals)

Сигналы позволяют реагировать на события в системе (создание, изменение, удаление объектов).

Встроенные сигналы

  • pre_save, post_save — до и после сохранения.
  • pre_delete, post_delete — до и после удаления.
  • m2m_changed — изменение связи «многие ко многим».
  • request_started, request_finished — начало и завершение запроса.

Регистрация обработчика

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

@receiver(post_save, sender=Article)
def send_notification(sender, instance, created, **kwargs):
if created:
# отправить уведомление
pass

Или вручную:

post_save.connect(send_notification, sender=Article)

Рекомендации

  • Избегайте сложной логики в сигналах — они усложняют отладку.
  • Используйте сигналы для кэширования, логирования, уведомлений.

11. Middleware

Middleware — это компоненты, обрабатывающие запросы до представления и ответы после него.

Стандартные middleware

Уже перечислены в разделе «Настройки», но ключевые функции:

  • SecurityMiddleware — защита от кликджекинга, XSS, HSTS.
  • SessionMiddleware — управление сессиями.
  • CsrfViewMiddleware — защита от CSRF-атак.
  • AuthenticationMiddleware — привязка пользователя к запросу.

Создание собственного middleware

class SimpleMiddleware:
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
# Код до вызова представления
response = self.get_response(request)
# Код после вызова представления
return response

Регистрация в MIDDLEWARE:

MIDDLEWARE = [
...
'myapp.middleware.SimpleMiddleware',
]

Методы middleware

  • process_request(request) — обработка запроса.
  • process_view(request, view_func, view_args, view_kwargs) — перед вызовом представления.
  • process_exception(request, exception) — при возникновении исключения.
  • process_response(request, response) — обработка ответа.

12. Тестирование

Django предоставляет мощную систему тестирования на основе unittest.

Типы тестов

  • Unit tests — проверка отдельных функций или методов.
  • Integration tests — проверка взаимодействия компонентов.
  • Functional tests — проверка сквозного поведения (часто через LiveServerTestCase).

Базовый класс**

from django.test import TestCase
from .models import Article

class ArticleTestCase(TestCase):
def setUp(self):
Article.objects.create(title="Тест", content="...")

def test_article_title(self):
article = Article.objects.get(title="Тест")
self.assertEqual(article.title, "Тест")

Клиент для тестирования HTTP

def test_home_page(self):
response = self.client.get('/')
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Добро пожаловать")

Фикстуры и фабрики

  • Fixtures — JSON/YAML файлы с начальными данными.
  • Factory Boy — сторонняя библиотека для генерации тестовых данных.

Запуск тестов

  • python manage.py test — запуск всех тестов.
  • python manage.py test myapp.tests.ArticleTestCase — запуск конкретного класса.

13. Управление статикой и медиа

Статические файлы

  • Размещаются в static/ внутри приложений или в STATICFILES_DIRS.
  • В шаблонах: {% load static %} <link href="{% static 'css/style.css' %}" rel="stylesheet">
  • В продакшене: python manage.py collectstatic собирает всё в STATIC_ROOT.

Медиафайлы

  • Загружаются в MEDIA_ROOT.
  • Доступны по URL MEDIA_URL.
  • В разработке требуется настройка маршрутов:
    from django.conf import settings
    from django.conf.urls.static import static

    if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

14. Безопасность

Django включает множество встроенных механизмов защиты:

  • CSRF-токены — обязательны для POST-форм.
  • XSS-защита — автоматическое экранирование переменных в шаблонах.
  • SQL-инъекции — предотвращаются использованием ORM.
  • Clickjacking protection — заголовок X-Frame-Options.
  • Password hashing — используется PBKDF2 или Argon2.
  • Rate limiting — не встроен, но реализуется через middleware или Redis.

Рекомендуется регулярно обновлять Django и использовать django-check или bandit для аудита.


15. Производительность

Оптимизация запросов

  • select_related() — жадная загрузка связей «один ко многим».
  • prefetch_related() — жадная загрузка связей «многие ко многим».
  • only(), defer() — выборка только нужных полей.
  • count(), exists() — эффективные проверки вместо len(queryset).

Кэширование

  • Шаблонное кэширование: {% cache 600 sidebar %}...{% endcache %}
  • Кэширование представлений: @cache_page(600)
  • Низкоуровневое кэширование: cache.set('key', value, timeout)

Профилирование

  • django-debug-toolbar — инструмент для разработки.
  • Логирование медленных запросов через LOGGING.

16. Развёртывание

Подготовка к продакшену

  • Установить DEBUG = False
  • Настроить ALLOWED_HOSTS
  • Настроить статику через Nginx/Apache
  • Использовать Gunicorn/uWSGI + Nginx
  • Настроить SSL
  • Настроить резервное копирование БД

Проверка конфигурации

python manage.py check --deploy

Среды

  • Использовать .env файлы (через python-decouple или django-environ)
  • Отдельные settings/production.py, settings/development.py

Docker

Типичный Dockerfile:

FROM python:3.11
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "myproject.wsgi:application"]

17. REST API с Django REST Framework (DRF)

Django REST Framework — мощное расширение для создания API.

Установка

pip install djangorestframework

Добавить в INSTALLED_APPS:

INSTALLED_APPS = [
...
'rest_framework',
]

Сериализаторы

Преобразуют объекты Python в JSON и обратно.

from rest_framework import serializers
from .models import Article

class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ['id', 'title', 'content', 'author']

Поддержка вложенных объектов:

author = UserSerializer(read_only=True)

Валидация:

def validate_title(self, value):
if "спам" in value.lower():
raise serializers.ValidationError("Заголовок содержит запрещённое слово")
return value

Представления API

Функциональные представления с декораторами

from rest_framework.decorators import api_view
from rest_framework.response import Response

@api_view(['GET'])
def article_list(request):
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)

Классовые представления

  • APIView — базовый класс.
  • GenericAPIView + миксины (ListModelMixin, CreateModelMixin).
  • ListCreateAPIView, RetrieveUpdateDestroyAPIView — готовые CRUD-классы.
from rest_framework.generics import ListCreateAPIView

class ArticleList(ListCreateAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer

Роутеры и автоматическая маршрутизация

from rest_framework.routers import DefaultRouter
from .views import ArticleViewSet

router = DefaultRouter()
router.register(r'articles', ArticleViewSet)
urlpatterns = router.urls

ViewSet объединяет действия:

from rest_framework.viewsets import ModelViewSet

class ArticleViewSet(ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer

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

  • Authentication classes: SessionAuthentication, TokenAuthentication, JWTAuthentication.
  • Permission classes: IsAuthenticated, IsAdminUser, DjangoModelPermissions.

Настройка по умолчанию в settings.py:

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}

18. Асинхронные возможности

Начиная с Django 3.1, фреймворк поддерживает асинхронные представления, middleware и ORM-вызовы (с ограничениями).

Асинхронные представления

async def async_view(request):
# Асинхронный вызов внешнего API
data = await fetch_external_data()
return JsonResponse({'data': data})

Асинхронные CBV

from django.utils.decorators import classonlymethod

class AsyncView(View):
@classonlymethod
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs)
view._is_coroutine = asyncio.coroutines._is_coroutine
return view

async def get(self, request):
return JsonResponse({'status': 'ok'})

Ограничения ORM

ORM остаётся синхронной. Для асинхронного доступа к БД требуется:

  • Использовать sync_to_async:
    from asgiref.sync import sync_to_async

    articles = await sync_to_async(Article.objects.all)()
  • Или перейти на django-async-orm (экспериментальные решения).

ASGI-сервер

Для запуска асинхронных приложений требуется ASGI-сервер (например, Daphne, Uvicorn):

uvicorn myproject.asgi:application

19. Расширенные техники ORM

Агрегация и аннотация

from django.db.models import Count, Avg

# Подсчёт комментариев к каждой статье
Article.objects.annotate(comment_count=Count('comments'))

# Средний рейтинг
Article.objects.aggregate(avg_rating=Avg('rating'))

Условные выражения

from django.db.models import Case, When, IntegerField

Article.objects.annotate(
priority=Case(
When(rating__gte=5, then=1),
default=0,
output_field=IntegerField()
)
)

Необработанные SQL-запросы

Article.objects.raw('SELECT * FROM blog_article WHERE title LIKE %s', ['%Django%'])

Или через курсор:

from django.db import connection

with connection.cursor() as cursor:
cursor.execute("UPDATE blog_article SET views = views + 1 WHERE id = %s", [pk])

20. Многоязычность (i18n/l10n)

Подготовка

  • Убедиться, что USE_I18N = True
  • Загрузить LocaleMiddleware в MIDDLEWARE

Перевод в коде

from django.utils.translation import gettext as _

title = _("Welcome")

Перевод в шаблонах

{% load i18n %}
<h1>{% trans "Welcome" %}</h1>
{% blocktrans with name=user.name %}Hello {{ name }}!{% endblocktrans %}

Создание переводов

django-admin makemessages -l ru
django-admin compilemessages

Файлы .po редактируются вручную или через Poedit.


21. Email и уведомления

Отправка письма

from django.core.mail import send_mail

send_mail(
subject='Тема',
message='Текст',
from_email='admin@example.com',
recipient_list=['user@example.com'],
fail_silently=False,
)

HTML-письма

from django.core.mail import EmailMultiAlternatives

msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()

Шаблонизация писем

from django.template.loader import render_to_string

html = render_to_string('emails/welcome.html', {'user': user})

22. Фоновые задачи

Django не выполняет задачи в фоне «из коробки». Используются сторонние решения:

Celery + Redis/RabbitMQ

  • Установка: pip install celery redis
  • Создание celery.py в проекте
  • Определение задач:
    from celery import shared_task

    @shared_task
    def send_welcome_email(user_id):
    user = User.objects.get(id=user_id)
    send_mail(...)
  • Вызов: send_welcome_email.delay(user.id)

Альтернативы

  • django-q
  • Huey
  • Простые cron-задачи через django-crontab

23. Мониторинг и логирование

Логирование

Конфигурация в settings.py:

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': BASE_DIR / 'logs/django.log',
},
},
'loggers': {
'myapp': {
'handlers': ['file'],
'level': 'INFO',
'propagate': True,
},
},
}

Использование:

import logging
logger = logging.getLogger('myapp')
logger.info("Пользователь %s вошёл", user.username)

Мониторинг

  • Sentry — сбор ошибок.
  • Prometheus + Grafana — метрики.
  • New Relic / Datadog — APM.

24. Архитектурные паттерны

Монолит

Стандартная структура Django — монолитное приложение. Подходит для MVP и средних проектов.

Микросервисы

  • Разделение на отдельные Django-проекты (API, auth, notifications).
  • Обмен через REST/gRPC.
  • Общая БД не рекомендуется.

Domain-Driven Design (DDD)

  • Приложения организуются по доменным зонам (orders, payments, users).
  • Чёткое разделение слоёв: модели → сервисы → представления.

Service Layer

Вынос бизнес-логики из представлений в отдельные функции:

# services.py
def create_article(title, content, author):
if Article.objects.filter(title=title).exists():
raise ValueError("Статья с таким заголовком уже существует")
return Article.objects.create(title=title, content=content, author=author)