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'); - сторонние приложения;
- собственные приложения проекта.
- встроенные приложения Django (
- 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 = MyModeltemplate_name = "list.html"context_object_name = "items"— имя переменной в шаблоне.paginate_by = 10— пагинация.
-
DetailView — отображает один объект.
model = MyModeltemplate_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-qHuey- Простые 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)