image
5 kwietnia 2023

Django: widoki oparte na funkcjach vs widoki oparte na klasach

5 kwietnia 2023

W świecie Django widoki odgrywają kluczową rolę w obsłudze przepływu danych między aplikacją a użytkownikiem. Określają, jak strona internetowa powinna odpowiedzieć na żądanie użytkownika i są odpowiedzialne za przetwarzanie wprowadzanych przez niego danych oraz zwracanie renderowanego szablonu lub odpowiedzi HTTP. Istnieją dwie podstawowe metody tworzenia widoków w Django: widoki oparte na funkcjach (Function-Based Views, FBVs) i widoki oparte na klasach (Class-Based Views, CBVs). Oba podejścia mają swoje zalety i ograniczenia, a zrozumienie tych różnic jest istotne dla deweloperów Django. W tym artykule omówimy główne różnice między FBVs i CBVs, przedstawimy przykłady obu podejść i pomożemy Ci określić, które podejście najlepiej pasuje do Twojego projektu.

 

 

Widoki oparte na funkcjach (FBVs)

 

Widoki oparte na funkcjach są tradycyjnym i najprostszym sposobem tworzenia widoków w Django. Jak sugeruje nazwa, są to po prostu funkcje w języku Python, które przyjmują obiekt żądania (request) jako argument i zwracają odpowiedź HTTP. Spójrzmy na podstawowy przykład FBV:

 

from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello, World!")

 

 

W tym przykładzie definiujemy widok o nazwie "hello", który przyjmuje obiekt żądania (request) jako argument i zwraca odpowiedź HTTP z tekstem "Hello, World!". Aby powiązać ten widok z adresem URL, musielibyśmy dodać go do pliku urls.py w ten sposób:

 

from django.urls import path
from . import views

urlpatterns = [
    path('hello/', views.hello, name='hello'),
]

 

 

Zalety FBVs:

 

Prostota: FBVs są łatwe do zrozumienia, szczególnie dla początkujących, ponieważ są to zwykłe funkcje w języku Python.

 

Otwartość: Kod w FBVs jest bardziej jawny, co ułatwia śledzenie przepływu danych i zrozumienie, co dzieje się na każdym etapie.

 

Ograniczenia FBVs:

 

Powtarzalność kodu: W miarę rozrastania się projektu i wzrostu jego złożoności, możesz zauważyć, że powtarzasz kod w wielu widokach, aby obsłużyć podobne funkcjonalności. Może to sprawić, że kod staje się trudniejszy do utrzymania i aktualizacji.

 

Mniejsza elastyczność: FBVs mogą stać się nieporęczne przy obsłudze skomplikowanych widoków, które wymagają wielu metod lub mixinów do obsługi różnych aspektów funkcjonalności widoku.

 

 

Class-Based Views (CBVs)

 

Widoki oparte na klasach, wprowadzone w Django 1.3, stanowią alternatywne podejście do tworzenia widoków. Zamiast korzystać z funkcji, CBVs wykorzystują klasy w języku Python i dziedziczą po wbudowanych w Django widokach generycznych, aby dostarczać wspólne funkcjonalności. Takie podejście może prowadzić do bardziej czytelnego i bardziej wielokrotnego użytku kodu, szczególnie w przypadku bardziej złożonych aplikacji. Przyjrzyjmy się podstawowemu przykładowi CBV:

 

from django.http import HttpResponse
from django.views import View

class HelloView(View):
    def get(self, request):
        return HttpResponse("Hello, World!")

 

W tym przykładzie definiujemy widok o nazwie HelloView, który dziedziczy po klasie bazowej View w Django. Następnie definiujemy metodę get, która obsługuje żądanie GET i zwraca odpowiedź HTTP z tekstem "Witaj, świecie!". Aby powiązać ten widok z adresem URL, musielibyśmy dodać go do pliku urls.py w ten sposób:

 

from django.urls import path
from . import views

urlpatterns = [
    path('hello/', views.HelloView.as_view(), name='hello'),
]

 

 

Zalety CBVs:

 

Powtarzalność kodu: CBVs promują wielokrotne wykorzystanie kodu poprzez dziedziczenie, umożliwiając tworzenie wspólnej klasy bazowej dla widoków z udostępnionymi funkcjonalnościami.

 

Modularność: CBVs ułatwiają organizację i strukturę złożonych widoków poprzez podzielenie ich na mniejsze, bardziej zarządzalne części.

 

Wbudowane widoki generyczne: Django dostarcza zestaw widoków generycznych, które zapewniają powszechnie stosowane funkcjonalności, takie jak tworzenie, aktualizacja i usuwanie obiektów, upraszczając proces tworzenia aplikacji.

 

Ograniczenia CBVs:

 

Krzywa uczenia: CBVs mogą być początkowo trudniejsze do zrozumienia dla początkujących ze względu na zależność od dziedziczenia i mixin-ów.

 

Skomplikowanie: Przepływ danych w CBVs może być mniej czytelny niż w FBVs, ponieważ może obejmować wiele warstw dziedziczenia, co utrudnia zrozumienie, co dzieje się na każdym etapie.

 

 

Konwersja widoku opartego na funkcji na widok oparty na klasie

 

Czasami możesz chcieć przekonwertować istniejący widok oparty na funkcji (FBV) na widok oparty na klasie (CBV), aby skorzystać z korzyści płynących z CBVs. Przejdźmy przez ten proces krok po kroku, korzystając z prostego przykładu. Rozpoczniemy od podstawowego FBV, który wyświetla listę elementów:

 

from django.shortcuts import render
from .models import Item

def item_list(request):
    items = Item.objects.all()
    return render(request, 'item_list.html', {'items': items})

 

 

Teraz przekonwertujmy ten FBV na CBV:

 

1. Zaimportuj niezbędne klasy i moduły:

 

from django.views import View
from django.shortcuts import render
from .models import Item

 

 

2. Utwórz nową klasę, która dziedziczy po klasie bazowej View w Django:

 

class ItemListView(View):

 

 

3. Zdefiniuj metodę get do obsługi żądania GET. Ta metoda powinna przyjmować obiekt żądania jako swój pierwszy argument, a następnie dodatkowe argumenty i argumenty kluczowe. Wewnątrz metody skopiuj logikę z oryginalnego FBV:

 

def get(self, request, *args, **kwargs):
    items = Item.objects.all()
    
    return render(request, 'item_list.html', {'items': items})

 

 

Cały CBV powinien wyglądać tak:

 

from django.views import View
from django.shortcuts import render
from .models import Item

class ItemListView(View):
    def get(self, request, *args, **kwargs):
        items = Item.objects.all()

        return render(request, 'item_list.html', {'items': items})

 

 

Na koniec zaktualizuj plik urls.py, aby używał nowego CBV:

 

from django.urls import path
from . import views

urlpatterns = [
    path('item_list/', views.ItemListView.as_view(), name='item_list'),
]

 

 

I to wszystko! Udało nam się pomyślnie przekonwertować widok oparty na funkcji na widok oparty na klasie.

 

 

Wspólne funkcjonalności w FBVs i CBVs

 

Pomimo swoich różnic, widoki oparte na funkcjach (FBVs) i widoki oparte na klasach (CBVs) mogą obsługiwać wiele tych samych funkcjonalności. W tej sekcji omówimy, jak obsługiwać żądania GET i POST, korzystać z dekoratorów oraz implementować paginację zarówno w FBVs, jak i w CBVs.

 

Obsługa żądań GET i POST

 

W FBVs możesz obsługiwać żądania GET i POST, sprawdzając metodę żądania:

 

from django.shortcuts import render

def my_view(request):
    if request.method == 'GET':
        # Handle GET request
    elif request.method == 'POST':
        # Handle POST request

 

W CBVs możesz obsługiwać żądania GET i POST, definiując osobne metody get i post:

 

from django.views import View
from django.shortcuts import render

class MyView(View):
    def get(self, request, *args, **kwargs):
        # Handle GET request

    def post(self, request, *args, **kwargs):
        # Handle POST request

 

 

Korzystanie z dekoratorów w FBVs i CBVs

 

Dekoratory są potężnym narzędziem do modyfikowania zachowania widoków. W FBVs możesz zastosować dekoratory bezpośrednio do funkcji widoku:

 

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    # Your view logic here

 

 

W CBVs możesz zastosować dekoratory za pomocą dekoratora @method_decorator na konkretnej metodzie:

 

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views import View

class MyView(View):
    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

 

 

Paginacja

 

Django zapewnia wbudowane wsparcie dla paginacji. Oto, jak zaimplementować paginację zarówno w FBVs, jak i w CBVs:

 

W FBVs:

 

from django.core.paginator import Paginator
from django.shortcuts import render
from .models import Item

def item_list(request):
    items = Item.objects.all()
    paginator = Paginator(items, 25) # Show 25 items per page

    page = request.GET.get('page')
    items = paginator.get_page(page)
    
    return render(request, 'item_list.html', {'items': items})

 

 

W CBVs:

 

from django.core.paginator import Paginator
from django.views import View
from django.shortcuts import render
from .models import Item

class ItemListView(View):
    def get(self, request, *args, **kwargs):
        items = Item.objects.all()
        paginator = Paginator(items, 25) # Show 25 items per page

        page = request.GET.get('page')
        items = paginator.get_page(page)
        return render(request, 'item_list.html', {'items': items})

 

 

Kiedy wybrać widoki oparte na funkcjach lub widoki oparte na klasach

 

Decyzja, czy wybrać widoki oparte na funkcjach (FBVs) czy widoki oparte na klasach (CBVs), zależy od różnych czynników. Poniżej przedstawiamy kilka czynników, które mogą pomóc Ci podjąć świadomą decyzję.

 

Złożoność widoku: Jeśli Twój widok ma prostą logikę, taką jak wyświetlanie szablonu lub zwracanie podstawowej odpowiedzi HTTP, lepszym wyborem mogą być widoki oparte na funkcjach, ponieważ są łatwiejsze do zrozumienia i wymagają mniej kodu. Z drugiej strony, jeśli Twój widok wymaga wielu metod lub mixinów do obsługi różnych aspektów funkcjonalności, widoki oparte na klasach mogą zapewnić lepszą organizację i modularność.

 

Wielokrotnego użytku kodu: Jeśli powtarzasz kod w wielu widokach, warto rozważyć użycie widoków opartych na klasach. Promują one wielokrotne wykorzystanie kodu poprzez dziedziczenie, co umożliwia tworzenie wspólnej klasy bazowej dla widoków z udostępnionymi funkcjonalnościami.

 

Wbudowane widoki generyczne: Django dostarcza zestaw wbudowanych widoków opartych na klasach, które mogą upraszczać proces tworzenia aplikacji dla powszechnych zadań, takich jak tworzenie, aktualizacja i usuwanie obiektów. Jeśli potrzebujesz zaimplementować te funkcjonalności, użycie widoków opartych na klasach może zaoszczędzić czas i wysiłek.

 

Znajomość i komfort: Twoje osobiste doświadczenie i poziom komfortu z widokami opartymi na funkcjach i widokami opartymi na klasach odgrywają istotną rolę w wyborze między tymi dwoma podejściami. Jeśli czujesz się bardziej komfortowo z jednym podejściem niż z drugim, możesz być bardziej produktywny i pisać czytelniejszy i bardziej zrozumiały kod, korzystając z podejścia, z którym jesteś zaznajomiony.

 

Pamiętaj, że możesz używać zarówno widoków opartych na funkcjach, jak i widoków opartych na klasach w swoich projektach Django. To nie jest decyzja "wszystko albo nic"; możesz wybrać podejście, które najlepiej odpowiada wymaganiom każdego widoku.

 

 

Podsumowanie

 

W tym artykule omówiliśmy główne różnice między widokami opartymi na funkcjach (FBVs) a widokami opartymi na klasach (CBVs) w Django, w tym przykłady tworzenia obu typów widoków oraz konwersji widoku opartego na funkcji na widok oparty na klasie. Omówiliśmy również, jak obsługiwać wspólne funkcjonalności, takie jak żądania GET i POST, dekoratory oraz paginację, w obu podejściach.

 

Ostateczny wybór między widokami opartymi na funkcjach a widokami opartymi na klasach zależy od wymagań Twojego projektu, Twojego doświadczenia z Django i Twoich osobistych preferencji. Jako początkujący programista ważne jest, aby zrozumieć oba podejścia i eksperymentować z nimi w swoich projektach, aby określić, które z nich najlepiej odpowiada Twoim potrzebom.

 

Z praktyką i doświadczeniem będziesz w stanie podejmować świadome decyzje dotyczące wyboru między widokami opartymi na funkcjach a widokami opartymi na klasach, co pomoże Ci tworzyć czyste, wydajne i łatwe do utrzymania aplikacje w Django.

Dyskusja

psewtfmoi

13 marca 2024

Twój komentarz

Tagi