Szukaj…


Wprowadzenie

Widoki ogólne to widoki, które wykonują określoną z góry akcję, taką jak tworzenie, edytowanie lub usuwanie obiektów lub po prostu wyświetlanie szablonu.

Widoki ogólne należy odróżnić od widoków funkcjonalnych, które są zawsze pisane ręcznie w celu wykonania wymaganych zadań. W skrócie można powiedzieć, że widoki ogólne należy skonfigurować, a widoki funkcjonalne należy zaprogramować.

Widoki ogólne mogą zaoszczędzić dużo czasu, zwłaszcza gdy masz wiele standardowych zadań do wykonania.

Uwagi

Te przykłady pokazują, że ogólne widoki znacznie upraszczają znormalizowane zadania. Zamiast programować wszystko od zera, konfigurujesz to, co inni ludzie już dla Ciebie zaprogramowali. Ma to sens w wielu sytuacjach, ponieważ pozwala bardziej skoncentrować się na projektach, a nie na procesach w tle.

Czy zawsze powinieneś ich używać? Nie. Mają sens tylko, o ile Twoje zadania są dość standaryzowane (ładowanie, edycja, usuwanie obiektów) i im bardziej powtarzalne są twoje zadania. Użycie jednego określonego widoku ogólnego tylko raz, a następnie zastąpienie wszystkich jego metod w celu wykonania bardzo specyficznych zadań może nie mieć sensu. Tutaj może być lepiej z funkcjonalnym widokiem.

Jeśli jednak masz wiele widoków wymagających tej funkcji lub jeśli twoje zadania dokładnie pasują do zdefiniowanych zadań określonego widoku ogólnego, wówczas widoki ogólne są dokładnie tym, czego potrzebujesz, aby ułatwić Ci życie.

Minimalny przykład: widoki funkcjonalne vs. ogólne

Przykład funkcjonalnego widoku do utworzenia obiektu. Bez komentarzy i pustych wierszy potrzebujemy 15 wierszy kodu:

# imports
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect

from .models import SampleObject
from .forms import SampleObjectForm

# view functioon
def create_object(request):
    
    # when request method is 'GET', show the template
    if request.method == GET:
        # perform actions, such as loading a model form
        form = SampleObjectForm()
        return render_to_response('template.html', locals())
    
    # if request method is 'POST', create the object and redirect
    if request.method == POST:
        form = SampleObjectForm(request.POST)

        # save object and redirect to success page if form is valid
        if form.is_valid:
            form.save()
            return HttpResponseRedirect('url_to_redirect_to')

        # load template with form and show errors
        else:
            return render_to_response('template.html', locals())

Przykład „Ogólnego widoku opartego na klasach” w celu wykonania tego samego zadania. Potrzebujemy tylko 7 linii kodu, aby osiągnąć to samo zadanie:

from django.views.generic import CreateView

from .models import SampleObject
from .forms import SampleObjectForm

class CreateObject(CreateView):
    model = SampleObject
    form_class = SampleObjectForm
    success_url = 'url_to_redirect_to'

Dostosowywanie widoków ogólnych

Powyższy przykład działa tylko wtedy, gdy twoje zadania są całkowicie standardowe. Na przykład nie dodajesz dodatkowego kontekstu.

Zróbmy bardziej realistyczny przykład. Załóżmy, że chcemy dodać tytuł strony do szablonu. W widoku funkcjonalnym działałoby to tak - z tylko jedną dodatkową linią:

def create_object(request):
    page_title = 'My Page Title'

    # ...

    return render_to_response('template.html', locals())

Jest to trudniejsze (lub: przeciwne do intuicyjnego) do osiągnięcia w przypadku widoków ogólnych. Ponieważ są one oparte na klasach, należy zastąpić jedną lub kilka metod klasy, aby osiągnąć pożądany wynik. W naszym przykładzie musimy przesłonić klasową metodę get_context_data w następujący sposób:

class CreateObject(CreateView):
    model = SampleObject
    form_class = SampleObjectForm
    success_url = 'url_to_redirect_to'

    def get_context_data(self, **kwargs):
        
        # Call class's get_context_data method to retrieve context
        context = super().get_context_data(**kwargs) 
        
        context['page_title'] = 'My page title'
        return context

Tutaj potrzebujemy czterech dodatkowych wierszy do zakodowania zamiast tylko jednego - przynajmniej dla pierwszej dodatkowej zmiennej kontekstowej, którą chcemy dodać.

Ogólne widoki z Mixins

Prawdziwa moc ogólnych widoków ujawnia się, gdy połączysz je z Mixinami. Mixin to kolejna zdefiniowana przez ciebie klasa, której metody mogą być dziedziczone przez twoją klasę widoku.

Załóżmy, że chcesz, aby każdy widok wyświetlał dodatkową zmienną „page_title” w szablonie. Zamiast przesłonić metodę get_context_data za każdym razem, gdy definiujesz widok, tworzysz mixin za pomocą tej metody i pozwalasz, aby twoje widoki dziedziczyły po tym mixinie. Brzmi bardziej skomplikowane niż jest w rzeczywistości:

# Your Mixin
class CustomMixin(object):
    
    def get_context_data(self, **kwargs):
        
        # Call class's get_context_data method to retrieve context
        context = super().get_context_data(**kwargs) 
        
        context['page_title'] = 'My page title'
        return context

# Your view function now inherits from the Mixin
class CreateObject(CustomMixin, CreateView):
    model = SampleObject
    form_class = SampleObjectForm
    success_url = 'url_to_redirect_to'

# As all other view functions which need these methods
class EditObject(CustomMixin, EditView):
    model = SampleObject
    # ...

Piękno tego polega na tym, że kod staje się znacznie bardziej uporządkowany niż w przypadku widoków funkcjonalnych. Cała logika stojąca za konkretnymi zadaniami znajduje się w jednym miejscu i tylko w jednym miejscu. Zaoszczędzisz także ogromną ilość czasu, zwłaszcza gdy masz wiele widoków, które zawsze wykonują te same zadania, z wyjątkiem różnych obiektów



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow