Django 6.0 у 2026 році: складені первинні ключі, фонові завдання та питання для співбесід

Django 6.0 у 2026: складені первинні ключі через CompositePrimaryKey, вбудовані фонові завдання, template partials, CSP-middleware та питання для технічних співбесід.

Django 6.0 складені первинні ключі та фонові завдання

Django 6.0, випущений у грудні 2025 року, став найзначнішим оновленням фреймворку за останні кілька років. Ця версія додає до ORM складені первинні ключі (CompositePrimaryKey), вбудовану систему фонових завдань через декоратор @task, template partials для повторного використання фрагментів шаблонів та нативний middleware Content Security Policy. Кожна з цих функцій усуває залежність від сторонніх пакетів і спрощує архітектуру Django-проєктів у продакшені. Для розробників, які готуються до технічних співбесід у 2026 році, знання цих нововведень є обов'язковим.

Хронологія версій Django

Django дотримується передбачуваного циклу релізів із мажорною версією приблизно кожні 8 місяців. Django 5.2 LTS (квітень 2025) впровадив складені первинні ключі у стабільному вигляді. Django 6.0 (грудень 2025) повністю інтегрує їх з рештою ORM та додає систему фонових завдань, template partials і CSP-middleware. Django 6.1 перебуває у стадії активної розробки. Мінімальна версія Python — 3.12.

Складені первинні ключі з CompositePrimaryKey

Реляційні бази даних використовують складені первинні ключі для унікальної ідентифікації запису на основі комбінації двох або більше стовпців. До Django 5.2 моделювання такої структури вимагало обхідних рішень на кшталт unique_together або сторонніх пакетів. CompositePrimaryKey вирішує цю проблему безпосередньо на рівні ORM.

Найпоширеніший випадок використання — проміжна таблиця, де комбінація двох зовнішніх ключів формує унікальну ідентичність запису. Наступний приклад моделює інвентаризацію, де кожен продукт у кожному складі має відповідну кількість:

python
# models.py
from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=100)
    sku = models.CharField(max_length=20, unique=True)

class Warehouse(models.Model):
    code = models.CharField(max_length=10, primary_key=True)
    location = models.CharField(max_length=200)

class Inventory(models.Model):
    pk = models.CompositePrimaryKey("product_id", "warehouse_id")
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField(default=0)
    last_restocked = models.DateTimeField(auto_now=True)

Поле pk отримує назви стовпців бази даних (а не назви полів моделі). Django генерує обмеження PRIMARY KEY (product_id, warehouse_id) на рівні бази даних, гарантуючи унікальність без необхідності автоінкрементного поля id.

Запити до складених ключів в ORM

Взаємодія з ORM зберігає звичний інтерфейс. Складений ключ представлений як кортеж Python, що дозволяє фільтрувати, створювати та призначати записи безпосередньо:

python
# views.py
from .models import Inventory, Product, Warehouse

# Create records
laptop = Product.objects.create(name="Laptop Pro", sku="LP-001")
warehouse_a = Warehouse.objects.create(code="WH-A", location="Berlin")

item = Inventory.objects.create(
    product=laptop,
    warehouse=warehouse_a,
    quantity=50
)

# Access the composite pk as a tuple
print(item.pk)  # (1, "WH-A")

# Filter by composite pk
result = Inventory.objects.filter(pk=(1, "WH-A")).first()

# Assign a composite pk directly
new_item = Inventory(pk=(2, "WH-B"))
print(new_item.product_id)  # 2
print(new_item.warehouse_id)  # "WH-B"

Ця функціональність особливо цінна для команд, які працюють з існуючими схемами баз даних або мігрують з інших ORM, де складені ключі вже підтримувались. Django Admin, серіалізатори DRF та система міграцій автоматично розпізнають моделі з CompositePrimaryKey. Варто зазначити обмеження: GenericForeignKey та пакети, що покладаються на цілочисельний pk, потребують адаптації для роботи з кортежами.

Вбудовані фонові завдання в Django 6.0

Django 6.0 інтегрує систему фонових завдань безпосередньо у фреймворк. Модуль django.tasks надає декоратор @task та метод .enqueue(), що дозволяють відкладати виконання функцій без налаштування зовнішнього брокера повідомлень чи окремих воркерів.

Ця система орієнтована на типові операції, які не повинні блокувати цикл HTTP-запит/відповідь: відправка електронних листів, генерація звітів, обробка файлів та виклики зовнішніх API. Визначення завдань слідує класичній конвенції Django — модуль tasks.py у кожному додатку:

python
# tasks.py
from django.tasks import task
from django.core.mail import send_mail

@task
def send_welcome_email(user_email, username):
    """Send a welcome email after user registration."""
    send_mail(
        subject="Welcome to the platform",
        message=f"Hello {username}, your account is ready.",
        from_email=None,  # uses DEFAULT_FROM_EMAIL
        recipient_list=[user_email],
    )
    return f"Email sent to {user_email}"

@task
def generate_report(report_id, format="pdf"):
    """Generate an export report asynchronously."""
    from .services import ReportService
    report = ReportService.generate(report_id, format=format)
    return report.file_path

Виклик завдання з view-функції здійснюється через метод .enqueue(), який серіалізує аргументи та передає їх налаштованому бекенду для асинхронного виконання:

python
# views.py
from .tasks import send_welcome_email, generate_report

def register_user(request):
    # ... user creation logic ...
    # Enqueue the task for background execution
    send_welcome_email.enqueue(
        user_email=user.email,
        username=user.username
    )
    return redirect("dashboard")

def export_view(request, report_id):
    generate_report.enqueue(report_id=report_id, format="csv")
    return JsonResponse({"status": "processing"})

Django 6.0 надає бекенд на основі бази даних за замовчуванням та Redis-бекенд для сценаріїв із більшим обсягом завдань. Налаштування TASKS у settings.py дозволяє обрати бекенд і задати параметри, такі як кількість воркерів та інтервал опитування.

Вбудовані завдання vs Celery

Вбудована система завдань Django 6.0 покриває прості та помірно складні сценарії. Для проєктів, що потребують маршрутизації завдань по чергах, складних workflow-ів (chains, chords), налаштовуваних політик повторних спроб з експоненційним відступом або розподіленої обробки на кількох серверах, Celery залишається оптимальним інструментом.

Template partials: повторно використовувані фрагменти шаблонів

Рушій шаблонів Django отримав функціональність, яку розробники фронтенд-фреймворків вважають базовою: можливість визначати повторно використовувані фрагменти в одному файлі та посилатися на них вибірково. Теги {% partialdef %} та {% endpartialdef %} дозволяють групувати кілька візуальних компонентів в одному шаблоні та використовувати лише потрібний фрагмент.

Наступний приклад визначає два представлення товару — картку для каталогу та рядок для інвентарної таблиці — в одному файлі шаблону:

html
<!-- templates/components/cards.html -->
{% partialdef product_card %}
<div class="card">
    <h3>{{ product.name }}</h3>
    <p class="price">{{ product.price|floatformat:2 }} EUR</p>
    <span class="stock {% if product.in_stock %}available{% else %}sold-out{% endif %}">
        {% if product.in_stock %}In Stock{% else %}Sold Out{% endif %}
    </span>
</div>
{% endpartialdef %}

{% partialdef product_row %}
<tr>
    <td>{{ product.name }}</td>
    <td>{{ product.price|floatformat:2 }} EUR</td>
    <td>{{ product.quantity }}</td>
</tr>
{% endpartialdef %}

Вибіркове включення partial здійснюється через синтаксис фрагмента #назва у тегу {% include %}:

html
<!-- templates/shop/catalog.html -->
{% extends "base.html" %}

{% block content %}
<div class="product-grid">
    {% for product in products %}
        {% include "components/cards.html#product_card" %}
    {% endfor %}
</div>
{% endblock %}

Головна перевага полягає у зменшенні кількості дрібних файлів. До появи template partials кожна візуальна варіація компонента вимагала окремого файлу. Тепер споріднені варіації співіснують в одному файлі, що спрощує навігацію та підтримку коду. Ця функціональність природно інтегрується з HTMX та іншими патернами часткового обміну HTML, де сервер повинен повертати конкретні фрагменти сторінки без повного рендерингу шаблону.

Готовий до співбесід з Django?

Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.

Нативний Content Security Policy Middleware

Захист від атак міжсайтового скриптингу (XSS) та ін'єкції контенту вимагає коректно налаштованих заголовків Content Security Policy. Django 6.0 інтегрує спеціалізований middleware та модуль django.utils.csp, що усувають необхідність зовнішніх пакетів на кшталт django-csp.

Конфігурація визначається у settings.py через словник, який зіставляє директиви CSP з дозволеними значеннями:

python
# settings.py
from django.utils.csp import CSP

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.security.ContentSecurityPolicyMiddleware",
    # ... other middleware
]

SECURE_CSP = {
    "default-src": [CSP.SELF],
    "script-src": [CSP.SELF, CSP.NONCE],
    "style-src": [CSP.SELF, "https://fonts.googleapis.com"],
    "img-src": [CSP.SELF, "https:", "data:"],
    "font-src": [CSP.SELF, "https://fonts.gstatic.com"],
    "connect-src": [CSP.SELF],
}

# Report-only mode for testing (does not block, only reports violations)
SECURE_CSP_REPORT_ONLY = {
    "default-src": [CSP.SELF],
    "report-uri": ["/csp-report/"],
}

Константа CSP.NONCE автоматично генерує унікальний nonce для кожного запиту та вставляє його у теги <script> шаблону. Це дозволяє виконувати легітимні інлайн-скрипти, водночас блокуючи будь-який скрипт, ін'єктований зловмисником. Режим SECURE_CSP_REPORT_ONLY особливо корисний під час розгортання: порушення фіксуються без блокування ресурсів, що дозволяє поступово уточнювати політики перед активацією режиму блокування.

Нативна інтеграція гарантує сумісність із рушієм шаблонів Django, включаючи автоматичну генерацію атрибутів nonce у блоках {% static %} та в інлайн-скриптах панелі адміністрування.

Інші важливі зміни у Django 6.0

Окрім ключових функцій, Django 6.0 містить покращення, що впливають на щоденну роботу розробника.

BigAutoField за замовчуванням: DEFAULT_AUTO_FIELD тепер вказує на BigAutoField у нових проєктах, знімаючи обмеження у 2,1 мільярда записів, яке накладав AutoField. Існуючі проєкти, де це значення не було задано явно, отримають попередження під час міграцій.

Асинхронна пагінація: пагіновані QuerySet тепер підтримують асинхронні методи, такі як await page.ahas_next() та await page.ahas_previous(). Асинхронні view-функції можуть пагінувати результати без блокування event loop, покращуючи пропускну здатність ASGI-застосунків.

Автоімпорти у shell: команда python manage.py shell автоматично імпортує всі моделі проєкту та найбільш використовувані модулі (django.db.models, django.utils.timezone, datetime). Це усуває рутинне написання імпортів при кожному відкритті інтерактивної сесії налагодження.

Модернізований API електронної пошти: модуль django.core.mail отримав нативну підтримку інлайн-вкладень, користувацьких заголовків та fluent-інтерфейсу, що спрощує складання складних листів без прямої маніпуляції з MIME-об'єктами.

Питання для технічних співбесід з Django у 2026 році

Технічні співбесіди на позиції Python-бекенд розробника у 2026 році дедалі частіше включають питання щодо функцій Django 6.0. Нижче наведені теми, які з найбільшою ймовірністю з'являться під час процесу відбору на Django-позиції.

Питання: Яка різниця між unique_together та CompositePrimaryKey?

unique_together створює обмеження унікальності на набір стовпців, але модель зберігає автоінкрементне поле id як первинний ключ. CompositePrimaryKey усуває поле id і встановлює комбінацію стовпців як справжній первинний ключ на рівні бази даних. Перше є додатковим обмеженням; друге переозначує саму ідентичність запису.

Питання: Коли обирати вбудовані завдання Django 6.0 замість Celery?

Нативна система підходить для простих завдань, що не потребують маршрутизації по чергах, складних механізмів повторних спроб чи workflow-ів типу canvas (chains, groups, chords). Celery є необхідним, коли застосунок вимагає розподіленої обробки на кількох серверах, розширеного періодичного планування (Celery Beat) або моніторингу в реальному часі через інструменти на кшталт Flower.

Питання: Як ContentSecurityPolicyMiddleware взаємодіє з nonce для інлайн-скриптів?

Middleware генерує унікальний криптографічний nonce для кожного HTTP-запиту. Константа CSP.NONCE у конфігурації SECURE_CSP вказує, що скрипти повинні мати відповідний атрибут nonce для виконання. Рушій шаблонів Django автоматично вставляє цей nonce у теги <script>, забезпечуючи виконання легітимних скриптів при одночасному блокуванні ін'єктованого коду.

Питання: Яку перевагу дають template partials порівняно з окремими include-файлами?

Template partials дозволяють визначати кілька повторно використовуваних фрагментів в одному файлі, зменшуючи кількість дрібних файлів та спрощуючи навігацію по кодовій базі. Синтаксис {% include "файл.html#назва" %} вибірково посилається на конкретний фрагмент, що природно інтегрується з патернами часткового обміну HTML, такими як HTMX.

Міграція з Django 5.2 на 6.0

При оновленні з Django 5.2 LTS до 6.0 слід перевірити сумісність сторонніх пакетів, оновити мінімальну версію Python до 3.12, переглянути попередження про DEFAULT_AUTO_FIELD та протестувати існуючі міграції. Рекомендується спочатку розгорнути Django 6.0 у staging-середовищі та поетапно активувати нові функції.

Висновок

  • Складені первинні ключі усувають необхідність штучних полів id у проміжних та зв'язувальних таблицях, узгоджуючи ORM Django зі стандартною реляційною моделлю баз даних
  • Вбудовані фонові завдання знижують операційну складність для простих асинхронних операцій, усуваючи залежність від зовнішнього брокера та окремих воркерів
  • Template partials організують повторно використовувані фрагменти в межах одного файлу, зменшуючи кількість шаблонів та полегшуючи інтеграцію з патернами часткового обміну HTML на кшталт HTMX
  • Нативний CSP-middleware забезпечує захист від XSS-атак з автоматичною генерацією nonce та режимом report-only для поетапного розгортання
  • BigAutoField за замовчуванням запобігає вичерпанню первинних ключів у таблицях із великим обсягом даних без додаткового налаштування
  • Асинхронна пагінація та автоімпорти у shell покращують щоденну продуктивність розробника як у продакшн-коді, так і в сесіях налагодження
  • Django 6.0 потребує Python 3.12+ та залишається сумісним з основними підтримуваними базами даних (PostgreSQL, MySQL, SQLite, Oracle)

Починай практикувати!

Перевір свої знання з нашими симуляторами співбесід та технічними тестами.

Теги

#django
#python
#composite-primary-keys
#background-tasks
#csp

Поділитися

Пов'язані статті