Najważniejsze w skrócie
- Aktualna wersja to Django 6.1.3 z 3 listopada 2026 r. Django 4.2 LTS nie dostaje poprawek bezpieczeństwa od 7 kwietnia 2026 r.
- Django 5.2 LTS ma poprawki bezpieczeństwa do kwietnia 2028 r. i jest ostatnią wersją dla Pythona 3.10 i 3.11. Django 6 wymaga Pythona 3.12 lub nowszego.
- Django 6.0 dodało zadania w tle (
django.tasks), fragmenty szablonów, wbudowaną politykę CSP i nowe API poczty. - Django 6.1 dodało tryby pobierania pól, które rozwiązują problem N+1 zapytań, usuwanie powiązanych rekordów po stronie bazy i ustawienie
MAILERS. Wymaga PostgreSQL 15 lub nowszego. - Django 6.2 LTS (kwiecień 2027 r.) zamknie dotychczasowy schemat. Od stycznia 2028 r. jedna wersja rocznie (Django 2028, 2029 i kolejne), każda z trzyletnim wsparciem i bez oznaczenia LTS.
Wersje Django i terminy wsparcia
Każda wersja Django ma dwa okresy wsparcia. W okresie głównym dostaje poprawki błędów, w rozszerzonym już tylko poprawki bezpieczeństwa i usunięcia błędów grożących utratą danych. Co trzecia wersja to LTS z około trzyletnim wsparciem.
| Wersja | Wydana | Python | Poprawki bezpieczeństwa do |
|---|---|---|---|
| 4.2 LTS | kwiecień 2023 r. | 3.8 do 3.12 | 7 kwietnia 2026 r. (koniec wsparcia) |
| 5.2 LTS | kwiecień 2025 r. | 3.10 do 3.14 | kwiecień 2028 r. |
| 6.0 | grudzień 2025 r. | 3.12 do 3.14 | kwiecień 2027 r. |
| 6.1 | sierpień 2026 r. | 3.12 do 3.15 | grudzień 2027 r. |
| 6.2 LTS (planowana) | kwiecień 2027 r. | 3.12 do 3.15 | kwiecień 2030 r. |
Daty według strony djangoproject.com/download i tabeli wersji Pythona w dokumentacji Django. Python 3.15 jest obsługiwany od Django 6.1.3.
Nowy cykl wydań od 2028 r.
Do tej pory nowa wersja Django wychodziła mniej więcej co 8 miesięcy. Django 6.2 będzie ostatnią wersją w tym schemacie. Od 2028 r. wersje będą wychodzić co roku w styczniu i nazywać się od roku: Django 2028, Django 2029 i tak dalej. Każda dostanie ten sam, trzyletni okres wsparcia, więc oznaczenie LTS przestaje być potrzebne.
Dla właściciela systemu to prostsza sytuacja: aktualizację Django można zaplanować raz w roku, w stałym terminie, i nie trzeba wybierać między wersją LTS a najnowszą. Twórcy Django zalecają aktualizację o jedną wersję naraz.
Zadania w tle w standardzie
Wysyłka e-maili, generowanie raportów czy import plików nie powinny blokować odpowiedzi dla użytkownika. Do tej pory każdy projekt rozwiązywał to po swojemu, najczęściej przez Celery. Django 6.0 dodaje wspólne API do definiowania i kolejkowania zadań (django.tasks):
# settings.py (środowisko deweloperskie)
TASKS = {"default": {"BACKEND": "django.tasks.backends.immediate.ImmediateBackend"}}
# tasks.py
from django.core.mail import send_mail
from django.tasks import task
@task(priority=2, queue_name="emails")
def email_users(emails, subject, message):
return send_mail(subject=subject, message=message, from_email=None, recipient_list=emails)
# w widoku
result = email_users.enqueue(emails=["jan@example.com"], subject="Witaj", message="...")
Ważne zastrzeżenie: Django nie zawiera procesu, który wykonuje zadania (workera). Dwa wbudowane backendy, ImmediateBackend i DummyBackend, są przeznaczone tylko do programowania i testów. Na produkcji potrzebny jest backend z zewnętrznej biblioteki, z workerem i trwałą kolejką. Istniejące rozwiązania, takie jak Celery, działają dalej. Wspólne API przyda się przede wszystkim w nowych projektach i w bibliotekach, które nie muszą już zakładać konkretnej kolejki.
Zadanie kolejkowane w transakcji warto zlecić dopiero po jej zatwierdzeniu (transaction.on_commit), żeby worker nie sięgnął po dane, których jeszcze nie ma w bazie.
Fragmenty szablonów i HTMX
Django 6.0 przejęło do rdzenia popularną bibliotekę django-template-partials. Fragment zdefiniowany znacznikiem {% partialdef %} można użyć wiele razy w tym samym szablonie albo wyrenderować osobno, podając jego nazwę po znaku #:
{% partialdef user-info inline %}
<div id="user-info-{{ user.username }}">
<h3>{{ user.name }}</h3>
</div>
{% endpartialdef %}
{% for user in featured %}
{% partial user-info %}
{% endfor %}
# widok zwraca tylko fragment, na przykład dla żądania z HTMX
return render(request, "authors.html#user-info", {"user": user})
To ważne dla aplikacji, które zamiast rozbudowanego frontendu w JavaScripcie używają HTMX: cała strona i jej odświeżane części mieszkają w jednym pliku szablonu, bez rozbijania go na dziesiątki małych plików. Przy wielu systemach dla firm i urzędów takie podejście w zupełności wystarcza. Piszemy o tym szerzej w porównaniu React czy Angular.
Wbudowana ochrona CSP
Content Security Policy to nagłówek, który mówi przeglądarce, skąd strona może ładować skrypty, style i obrazy. Dobrze ustawiony ogranicza skutki ataków XSS: nawet jeśli ktoś wstrzyknie skrypt, przeglądarka go nie wykona. Brak tego nagłówka to częsta uwaga w raportach z testów penetracyjnych aplikacji. Do tej pory w Django potrzebna była do tego zewnętrzna biblioteka, a od wersji 6.0 obsługa CSP jest wbudowana:
# settings.py
from django.utils.csp import CSP
MIDDLEWARE = [
# ...
"django.middleware.csp.ContentSecurityPolicyMiddleware",
]
SECURE_CSP = {
"default-src": [CSP.SELF],
"script-src": [CSP.SELF, CSP.NONCE],
"img-src": [CSP.SELF, "https:"],
}
<script nonce="{{ csp_nonce }}">...</script>
Jednorazowy kod nonce trafia do szablonów przez procesor kontekstu django.template.context_processors.csp. W Django 6.1 doszedł znacznik {% csp_nonce_attr %}, a szablony panelu administracyjnego dostają nonce automatycznie. Politykę najlepiej najpierw włączyć w trybie raportowania (SECURE_CSP_REPORT_ONLY) i dopiero po sprawdzeniu, co by zablokowała, przełączyć na tryb właściwy. Django nie zbiera raportów o naruszeniach, więc trzeba do tego osobnego adresu albo usługi.
ORM w Django 6.1: tryby pobierania i usuwanie w bazie
Najczęstszy problem z wydajnością aplikacji Django to tak zwane N+1 zapytań: pętla po liście rekordów, która przy każdym z nich osobno pobiera obiekt powiązany. Przy stu rekordach to sto jeden zapytań do bazy. Dotąd trzeba było pamiętać o select_related() albo prefetch_related(). Django 6.1 wprowadza tryby pobierania pól:
from django.db import models
books = Book.objects.fetch_mode(models.FETCH_PEERS)
for book in books:
print(book.author.name) # 2 zapytania zamiast jednego na każdą książkę
FETCH_ONEto dotychczasowe zachowanie i nadal ustawienie domyślne.FETCH_PEERSprzy pierwszym odwołaniu pobiera brakujące pole od razu dla wszystkich rekordów z tego samego zapytania, jakprefetch_related()na żądanie.FETCH_RAISEzgłasza wyjątekFieldFetchBlocked, gdy kod próbuje doczytać dane. Przydaje się w testach, żeby wyłapać N+1, zanim trafi na produkcję.
Druga nowość to usuwanie powiązanych rekordów po stronie bazy danych. Opcje DB_CASCADE, DB_SET_NULL i DB_SET_DEFAULT zamieniają się w klauzulę ON DELETE w SQL, więc Django nie musi wczytywać do pamięci wszystkich powiązanych obiektów przed usunięciem:
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.DB_CASCADE)
Ograniczenia: przy DB_CASCADE nie działają sygnały pre_delete i post_delete dla usuwanych w ten sposób rekordów, w tym samym i powiązanych modelach nie można mieszać tych opcji ze zwykłymi (poza DO_NOTHING), a DB_SET_DEFAULT wymaga db_default i nie działa w MySQL ani MariaDB.
Poczta i inne zmiany
Wysyłka e-maili przeszła na nowoczesne API z biblioteki standardowej Pythona: EmailMessage.message() zwraca obiekt email.message.EmailMessage, a stare klasy SafeMIMEText i SafeMIMEMultipart są przestarzałe. Parametry opcjonalne funkcji pocztowych trzeba podawać z nazwą. W Django 6.1 doszło ustawienie MAILERS, które pozwala skonfigurować kilka serwerów poczty, a dotychczasowe ustawienia EMAIL_* są przestarzałe:
MAILERS = {
"default": {
"BACKEND": "django.core.mail.backends.smtp.EmailBackend",
"OPTIONS": {"host": "smtp.example.com", "use_tls": True},
},
}
Pozostałe zmiany, które warto znać:
DEFAULT_AUTO_FIELDdomyślnie wskazujeBigAutoField. Projekty, które polegały na niejawnymAutoField, powinny ustawić go jawnie, żeby nie dostać niechcianych migracji.AsyncPaginatoriAsyncPagedo stronicowania w widokach asynchronicznych.- Agregaty
StringAggiAnyValuedla wszystkich baz danych, w 6.1 takżeBitAnd,BitOriBitXororaz funkcjeUUID4iUUID7. - Więcej iteracji PBKDF2 przy haszowaniu haseł: 1,2 mln w 6.0 i 1,5 mln w 6.1.
- W 6.1 poprawki dostępności formularzy w panelu administracyjnym.
Na co uważać przy aktualizacji
Django 6.0
- Wymaga Pythona 3.12 lub nowszego. Aplikacje na Pythonie 3.10 i 3.11 muszą najpierw zmienić wersję Pythona.
- Koniec obsługi MariaDB 10.5 i sterownika
cx_Oracle, wyższe minimalne wersje m.in. psycopg i Pillow. - Usunięte: argumenty pozycyjne w
Model.save()i parametrcheckwCheckConstraint(terazcondition).forms.URLFieldzakłada protokół https. - Własne implementacje
Field.pre_save()mogą być wywołane więcej niż raz.
Django 6.1
- Minimalne wersje baz: PostgreSQL 15, MySQL 8.4, MariaDB 10.11, SQLite 3.37.
first()ilast()po pustymorder_by()nie sortują już po kluczu głównym.- Aliasy w generowanym SQL są zawsze w cudzysłowach, więc surowe zapytania korzystające z aliasów pisanych wielkimi i małymi literami mogą wymagać poprawek.
- Zmieniły się klucze pamięci podręcznej stron i fragmentów szablonów. Po wdrożeniu pamięć podręczna zapełnia się od nowa, co przez chwilę zwiększa obciążenie.
- Przestarzałe: ustawienia
EMAIL_*iselect_related()bez argumentów.
Jeśli aplikacja korzysta z PostgreSQL 14 albo starszego, przed przejściem na Django 6.1 trzeba zaktualizować serwer bazy. To osobny projekt z kopią zapasową, testem i oknem serwisowym, więc warto go zaplanować z wyprzedzeniem.
Wagtail: która wersja do którego Django
W serwisach opartych na Wagtail wersję Django wyznacza CMS. Wagtail wydaje nową wersję co 3 miesiące, a co kilka wydań wersję LTS. Wagtail 7.0 LTS, ostatnia wersja dla Django 4.2, straciło wsparcie 2 listopada 2026 r.
| Wagtail | Django | Python | Wsparcie do |
|---|---|---|---|
| 7.4 LTS | 5.2, 6.0 | 3.10 do 3.14 | 2 listopada 2027 r. |
| 8.1 | 5.2, 6.0, 6.1 | 3.11 do 3.15 | 4 maja 2027 r. |
Według informacji o wydaniach i harmonogramu Wagtail. Następna wersja LTS jest planowana na maj 2027 r.
Dla serwisu, który ma działać stabilnie bez częstych zmian, polecamy dziś parę Wagtail 7.4 LTS i Django 5.2 LTS. Django 6.1 wymaga Wagtail 8.0 lub nowszego, czyli wersji bez długiego wsparcia, które trzeba aktualizować co kilka miesięcy.
Jak zaplanować aktualizację
Dokumentacja Django zaleca aktualizację krok po kroku, przez każdą kolejną wersję, za każdym razem do najnowszej wersji poprawkowej. Dotyczy to także przejścia z jednej wersji LTS na następną. Ostrzeżenia o przestarzałych funkcjach naprawia się przed zmianą wersji, bo w następnej wersji te funkcje znikają.
- Stan wyjściowyWersje Django, Pythona, bazy danych i wszystkich bibliotek. Sprawdzamy, które biblioteki są porzucone i czym je zastąpić.
- OstrzeżeniaTesty uruchomione z
python -Wa manage.py testpokazują wszystkie przestarzałe wywołania. Naprawiamy je jeszcze na obecnej wersji. - Kolejne wersjeZmiana o jedną wersję naraz, z lekturą informacji o wydaniu i pełnymi testami po każdym kroku. Razem z Django aktualizujemy zależne biblioteki.
- Środowisko testoweKopia danych z produkcji, migracje, zadania w tle, wysyłka poczty, eksporty i integracje.
- WdrożenieKopia zapasowa bazy przed migracjami, plan powrotu i obserwacja logów po wdrożeniu. Po zmianie kluczy pamięci podręcznej spodziewamy się chwilowo większego obciążenia.
- Aplikacje na Django 4.2 i starszym przeniesione na 5.2 LTS w pierwszej kolejności.
- Python 3.12 lub nowszy przed przejściem na Django 6.
- PostgreSQL 15 lub nowszy (albo MySQL 8.4, MariaDB 10.11) przed przejściem na Django 6.1.
- Brak ostrzeżeń o przestarzałych funkcjach w testach.
- Jawne
DEFAULT_AUTO_FIELDw ustawieniach. - W serwisach Wagtail wersja CMS dopasowana do docelowego Django.
- Stały termin corocznej aktualizacji w planie utrzymania, zgodny z nowym cyklem wydań.
Najczęstsze pytania
Czy aplikację na Django 4.2 trzeba zaktualizować?
Tak. Django 4.2 nie dostaje poprawek bezpieczeństwa od 7 kwietnia 2026 r., a ostatnim wydaniem jest 4.2.30. Najbliższy sensowny cel to Django 5.2 LTS, wspierane do kwietnia 2028 r., które działa jeszcze na Pythonie 3.10 i 3.11.
Zostać na Django 5.2 LTS czy przejść na 6.1?
Django 5.2 LTS jest bezpieczne do kwietnia 2028 r., więc nie ma pośpiechu. Jeśli aplikacja jest rozwijana, przejście na 6.1 daje nowe funkcje i ustawia projekt w rytmie corocznych aktualizacji. Jeśli tylko jest utrzymywana, rozsądnym celem jest Django 6.2 LTS z kwietnia 2027 r.
Czy django.tasks zastąpi Celery?
Samo nie. Django definiuje wspólne API zadań, ale nie zawiera workera, a wbudowane backendy służą tylko do programowania i testów. Na produkcji potrzebny jest backend z zewnętrznej biblioteki. Działające wdrożenia Celery nie wymagają zmian.
Co oznacza koniec wersji LTS od 2028 r.?
Od 2028 r. każda wersja Django będzie miała takie samo, trzyletnie wsparcie, więc osobne oznaczenie LTS przestaje być potrzebne. Nowe wersje będą wychodzić co roku w styczniu i nazywać się od roku, na przykład Django 2028.
Ile trwa aktualizacja Django?
Zależy od wieku aplikacji i jakości testów. Mała aplikacja z dobrymi testami przechodzi na kolejną wersję w kilka dni. Duży system, który przez kilka lat nie był aktualizowany, wymaga kilku tygodni, bo zwykle trzeba też wymienić porzucone biblioteki i zaktualizować bazę danych.
Źródła
- Django 6.0: informacje o wydaniu
- Django 6.1: informacje o wydaniu
- Django: obsługiwane wersje i terminy wsparcia
- Django: obsługiwane wersje Pythona
- Django: aktualizacja do nowej wersji
- Django: zadania w tle (django.tasks)
- Wagtail 8.1: informacje o wydaniu
- Wagtail: harmonogram wydań i wsparcia
Stan na 6 listopada 2026 r. Daty przyszłych wersji Django i Wagtail są planowane i mogą się zmienić.