# Django 6.0 у 2026 році: складені первинні ключі, фонові завдання та питання для співбесід > Django 6.0 у 2026: складені первинні ключі через CompositePrimaryKey, вбудовані фонові завдання, template partials, CSP-middleware та питання для технічних співбесід. - Published: 2026-06-09 - Updated: 2026-06-09 - Author: SharpSkill - Tags: django, python, composite-primary-keys, background-tasks, csp - Reading time: 10 min --- 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](/uk/blog/django/django-celery-async-tasks-interview-2026) залишається оптимальним інструментом. ## Template partials: повторно використовувані фрагменти шаблонів Рушій шаблонів Django отримав функціональність, яку розробники фронтенд-фреймворків вважають базовою: можливість визначати повторно використовувані фрагменти в одному файлі та посилатися на них вибірково. Теги `{% partialdef %}` та `{% endpartialdef %}` дозволяють групувати кілька візуальних компонентів в одному шаблоні та використовувати лише потрібний фрагмент. Наступний приклад визначає два представлення товару — картку для каталогу та рядок для інвентарної таблиці — в одному файлі шаблону: ```html {% partialdef product_card %}
{{ product.price|floatformat:2 }} EUR
{% if product.in_stock %}In Stock{% else %}Sold Out{% endif %}