Zaawansowane funkcje Django
W miarę rozwoju aplikacji Django pojawia się potrzeba korzystania z bardziej zaawansowanych mechanizmów. Django udostępnia middleware, sygnały, context processors oraz narzędzia do optymalizacji i cache’owania, które pozwalają pisać wydajniejsze i czystsze aplikacje.
1. Middleware – jak działa i jak tworzyć własne
1.1. Czym jest middleware?
Middleware to fragment kodu, który „owija” każde żądanie i odpowiedź w Django. Można go traktować jak łańcuch filtrów – każde żądanie HTTP przechodzi przez wszystkie middleware w kolejności, a każda odpowiedź wraca przez nie w odwrotnej kolejności.
Przykłady użycia middleware w Django:
- Obsługa sesji i ciasteczek,
- Uwierzytelnianie użytkowników,
- Obsługa wyjątków,
- Dodawanie nagłówków do odpowiedzi,
- Logowanie requestów.
1.2. Wbudowane middleware
W settings.py znajdziemy listę middleware:
1.3. Tworzenie własnego middleware
Własny middleware to klasa z metodami __init__, __call__ lub process_request / process_response.
Przykład – middleware logujący czas obsługi żądania:
Rejestracja w settings.py:
2. Sygnały (signals) i zastosowania
2.1. Czym są sygnały?
Signals pozwalają reagować na zdarzenia w aplikacji Django – np. utworzenie nowego obiektu, usunięcie użytkownika, zapis modelu. Dzięki temu możemy oddzielić logikę biznesową od reszty kodu.
2.2. Najczęściej używane sygnały Django
pre_save– przed zapisem obiektu,post_save– po zapisaniu obiektu,pre_delete– przed usunięciem,post_delete– po usunięciu,m2m_changed– zmiana relacji ManyToMany,request_started,request_finished– cykl żądania.
2.3. Przykład użycia – automatyczne tworzenie profilu użytkownika
Teraz przy każdym nowym użytkowniku tworzony jest automatycznie powiązany profil.
3. Context Processors
3.1. Czym są?
Context processors to funkcje, które dodają dodatkowe dane do kontekstu wszystkich szablonów Django. Dzięki temu w każdym widoku mamy dostęp do np. aktualnego roku, ustawień aplikacji czy globalnych zmiennych.
3.2. Przykład – dodanie aktualnego roku do każdego szablonu
Rejestracja w settings.py:
Teraz w każdym szablonie mamy dostęp do {{ current_year }}.
4. Cache i optymalizacja zapytań
4.1. Cache w Django
Cache pozwala na przechowywanie wyników kosztownych operacji (np. renderowania widoków, zapytań do bazy). Django wspiera różne backendy cache (np. memcached, redis, database cache, file-based cache).
Przykład – cache na poziomie widoku:
Przykład – cache szablonu:
4.2. Optymalizacja zapytań ORM
Django ORM bywa wygodny, ale może generować tzw. N+1 queries problem – czyli zbyt dużą liczbę zapytań do bazy.
select_related – dla relacji ForeignKey i OneToOne
Łączy tabelę przez JOIN i pobiera powiązany obiekt w jednym zapytaniu.
prefetch_related – dla relacji ManyToMany i odwrotnych ForeignKey
Działa podobnie, ale wykonuje dwa zapytania i łączy dane w pamięci Pythona.