Zapraszam do serii postów opisujących widoki klasowe w Django (Class Based Views). Będzie to rozwinięcie webinaru, w którym pokazałem jak szybko zbudować stronę internetową z wykorzystaniem CBV: Django w godzinę: Tworzenie aplikacji z Class Based Views.
Class-Based Views (CBV) i Function-Based Views (FBV) to dwa główne podejścia do tworzenia widoków w Django. Oba podejścia mają swoje zalety i wady, a wybór między nimi zależy od wielu czynników, takich jak poziom zaawansowania projektu, specyfika funkcjonalności, złożoność aplikacji czy preferencje programisty. W tym artykule porównam Class-Based Views i Function-Based Views. Od razu napiszę, że jestem stronniczy i preferuję Class Based Views.
Definicje
Class-Based Views to klasowe widoki, w których cała logika biznesowa jest zaimplementowana wewnątrz klas. CBV są obiektowe i wymagają od programisty przedefiniowania metod w klasie widoku, aby dostosować widok do swoich potrzeb. W Django istnieje wiele gotowych klas CBV, które można użyć w swoim projekcie.
Function-Based Views to funkcjonalne widoki, w których cała logika biznesowa jest zaimplementowana wewnątrz funkcji. FBV są proceduralne i polegają na przekazywaniu parametrów do funkcji i zwracaniu odpowiedzi HTTP. W Django można napisać swoje własne widoki funkcjonalne lub korzystać z gotowych funkcji udostępnianych przez framework.
Zalety i wady Function-Based Views
Zalety:
- Łatwe w zrozumieniu i pisaniu - funkcjonalne widoki są bardziej proceduralne i zrozumiałe dla początkujących programistów.
- Brak wymaganej znajomości programowania obiektowego - FBV polegają na pisaniu zwykłych funkcji, co nie wymaga od programisty znajomości programowania obiektowego.
Wady:
- Mniej czytelny kod - logika biznesowa jest rozproszona w wielu funkcjach, co może prowadzić do utraty przejrzystości kodu.
- Wymaga więcej kodu - w funkcjonalnych widokach większość rzeczy, takich jak obsługa żądań HTTP, musi być zaimplementowana ręcznie przez programistę.
- Dokumentacja Django zdaje się "promować" widoki funkcyjne, np. poprzez wykorzystanie ich w tutorialach: https://docs.djangoproject.com/pl/4.2/intro/tutorial03/
Zalety i wady Class-Based Views
Zalety:
- Przejrzysty kod i łatwa konserwacja - logika biznesowa jest zgrupowana w jednym miejscu, co ułatwia utrzymanie i rozwijanie kodu.
- Mniej kodu do napisania - wiele czynności jest realizowanych automatycznie przez Django, co pozwala na skrócenie czasu pisania kodu.
- Proste dziedziczenie - klasowe widoki w Django są podzielone na hierarchię klas, co ułatwia dziedziczenie, dostosowywanie i rozszerzanie widoków.
Wady:
- Wymaga znajomości programowania obiektowego - CBV polegają na dziedziczeniu klas i przedefiniowaniu metod, co wymaga od programisty znajomości programowania obiektowego.
- Może prowadzić do nadmiernego skomplikowania kodu - zbyt wiele dziedziczenia klas może prowadzić do utraty przejrzystości kodu.
Porównanie Class-Based Views i Function-Based Views
W Django istnieje wiele gotowych klas CBV i funkcji FBV, które można wykorzystać do tworzenia widoków. Poniżej przedstawiam porównanie kilku z nich.
Obsługa formularzy
W CBV formularze są zwykle obsługiwane za pomocą klasy FormView, która automatycznie obsługuje walidację i renderowanie formularza. W FBV formularze są obsługiwane za pomocą funkcji renderującej formularz i obsługującej żądanie HTTP POST.
# przykład obsługi formularza za pomocą klasy FormView
from django.views.generic.edit import FormView
from myapp.forms import MyForm
class MyFormView(FormView):
template_name = 'myapp/form.html'
form_class = MyForm
success_url = '/success/'
# przykład obsługi formularza za pomocą funkcji widoku
from django.shortcuts import render
from myapp.forms import MyForm
def my_form_view(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
# obsługa formularza
return HttpResponseRedirect('/success/')
else:
form = MyForm()
return render(request, 'myapp/form.html', {'form': form})
Wnioski: widok funkcyjny wymaga zdecydowanie więcej kodu i wiedzy od programisty. Co więcej, ten kod trzeba powtórzyć na każdej stronie, która zawiera formularz - copy/paste + poprawki. Przykład obsługi FormView można zobaczyć na webinarze tutaj: https://youtu.be/2S9-pvFBlBc?t=3079
Dziedziczenie widoków
W CBV dziedziczenie klas jest łatwe i intuicyjne, co pozwala na dostosowanie i rozszerzenie widoków w prosty sposób. W FBV dziedziczenie prowadzi do utraty czytelności kodu i często nie jest stosowane.
# przykład dziedziczenia klasy widoku w CBV
from django.views.generic import ListView
from myapp.models import MyModel
class MyModelListView(ListView):
model = MyModel
template_name = 'myapp/my_model_list.html'
class AnotherMyModelListView(MyModelListView):
template_name = 'myapp/another_my_model_list.html'
# przykład dziedziczenia w FBV (mniej czytelne)
from django.shortcuts import render
from django.http import HttpResponse
def product_list(request):
products = Product.objects.all()
return render(request, 'product_list.html', {'products': products})
def search_products(request):
query = request.GET.get('q', '')
# tutaj występuje "dziedziczenie" -> products wywołuje funckję "products_list"
products = product_list(request).context_data['products'].filter(name__icontains=query)
return render(request, 'product_list.html', {'products': products, 'query': query})
Czytelność kodu
W CBV kod jest zwykle bardziej przejrzysty i łatwiejszy w konserwacji, ponieważ logika biznesowa jest zgrupowana w jednym miejscu. W FBV kod jest rozproszony w wielu funkcjach i może być trudniejszy w konserwacji, zwłaszcza w większych projektach.
Kiedy używać Class-Based Views a kiedy Function-Based Views
Ostateczna decyzja, czy użyć CBV czy FBV, zależy od wielu czynników, takich jak poziom zaawansowania projektu, specyfika funkcjonalności, złożoność aplikacji czy preferencje programisty. Niemniej jednak, istnieją pewne wytyczne, które można zastosować do wyboru odpowiedniego podejścia.
Kiedy używać Class-Based Views
- Gdy projekt jest prosty do wykonania, np. strona "wizytówka" - widok może zawierać dosłownie 3 linijki.
- Gdy projekt jest skomplikowany i wymaga złożonych widoków, które wymagają dużo powtarzającego się kodu.
- Gdy potrzebna jest łatwość dziedziczenia i rozszerzania widoków.
- Gdy projekt wymaga widoków, które dostarczają wiele wbudowanych funkcjonalności (na przykład obsługa formularzy, paginacja itp.).
- Gdy potrzebne są widoki związanego z modelem, takie jak CRUD (Create, Retrieve, Update, Delete), na przykład formularz rejestracji użytkownika, kontaktowy.
Kiedy używać Function-Based Views
- Gdy projekt jest prosty i nie wymaga dużych, złożonych widoków.
- Gdy potrzebna jest prostota kodu i brak niepotrzebnych warstw abstrakcji.
- Gdy potrzebne są widoki, które obsługują jedynie jedno żądanie HTTP, bez konieczności dziedziczenia i rozszerzania.
Podsumowanie
Widoki są kluczowym elementem każdej aplikacji Django i są często punktem wejścia dla użytkownika. Zarówno Class-Based Views, jak i Function-Based Views mają swoje wady i zalety, a wybór odpowiedniego podejścia zależy od specyfiki projektu i preferencji programisty.
Ja osobiście preferuję Class Based Views. Uważam je za czytelniejsze. Zarówno w prostych, jak i skomplikowanych projektach wymagają mniejszej ilości kodu. Dziedzicznie pozwala na ich łatwe rozszerzanie, a gratisy w postaci obsługi formularzy, automatycznego generowania widoku, przekazywania contextu itp, uważam za bardzo pomocne. Polecam świetny zbiór informacji: Classy Class-Based Views oraz oczywiście dokumentację Django.
Spodobał Ci się post?
Podziel się nim!
Masz uwagi do posta, chcesz porozmawiać, szukasz pomocy z Pythonem i Django? Napisz do mnie!
1 thought on “Django Class Based Views: Wprowadzenie i porównanie z widokami funkcyjnymi”
Comments are closed.