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.

Łączy tabelę przez JOIN i pobiera powiązany obiekt w jednym zapytaniu.


Działa podobnie, ale wykonuje dwa zapytania i łączy dane w pamięci Pythona.