Ricerca…


introduzione

Le viste generiche sono viste che eseguono una determinata azione predefinita, come la creazione, la modifica o l'eliminazione di oggetti o semplicemente la visualizzazione di un modello.

Le viste generiche devono essere distinte dalle viste funzionali, che sono sempre scritte a mano per eseguire le attività richieste. In breve, si può dire che le viste generiche devono essere configurate, mentre le viste funzionali devono essere programmate.

Le viste generiche possono risparmiare molto tempo, specialmente quando si devono eseguire molte attività standardizzate.

Osservazioni

Questi esempi mostrano che le viste generiche generalmente semplificano le attività standardizzate. Invece di programmare tutto da capo, puoi configurare ciò che altre persone hanno già programmato per te. Questo ha senso in molte situazioni, in quanto consente di concentrarsi maggiormente sulla progettazione dei progetti piuttosto che sui processi in background.

Quindi, dovresti sempre usarli? No. Hanno senso solo se i tuoi compiti sono abbastanza standardizzati (caricamento, modifica, eliminazione di oggetti) e più ripetitivi sono i tuoi compiti. L'utilizzo di una vista generica specifica solo una volta e quindi l'annullamento di tutti i suoi metodi per eseguire attività molto specifiche potrebbe non avere senso. Potresti star meglio con una vista funzionale qui.

Tuttavia, se disponi di molte viste che richiedono questa funzionalità o se le tue attività corrispondono esattamente alle attività definite di una vista generica specifica, le visualizzazioni generiche sono esattamente ciò di cui hai bisogno per semplificarti la vita.

Esempio minimo: viste funzionali e generiche

Esempio per una vista funzionale per creare un oggetto. Escludendo i commenti e le righe vuote, abbiamo bisogno di 15 righe di codice:

# 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())

Esempio di una 'vista generica basata su classi' per eseguire la stessa operazione. Abbiamo solo bisogno di 7 linee di codice per ottenere lo stesso compito:

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'

Personalizzazione delle viste generiche

L'esempio precedente funziona solo se le tue attività sono interamente attività standard. Ad esempio, non aggiungi qui un contesto extra.

Facciamo un esempio più realistico. Supponiamo di voler aggiungere un titolo di pagina al modello. Nella vista funzionale, funzionerebbe in questo modo - con una sola riga aggiuntiva:

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

    # ...

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

Questo è più difficile (o: controtestivo) da ottenere con visualizzazioni generiche. Poiché sono basati su classi, devi eseguire l'override di uno o più metodi della classe per ottenere il risultato desiderato. Nel nostro esempio, abbiamo bisogno di sovrascrivere il metodo get_context_data della classe in questo modo:

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

Qui, abbiamo bisogno di quattro righe aggiuntive da codificare invece di una sola, almeno per la prima variabile di contesto che vogliamo aggiungere.

Visualizzazioni generiche con Mixins

Il vero potere delle viste generiche si sviluppa quando le combini con Mixins. Un mixin è solo un'altra classe definita da te i cui metodi possono essere ereditati dalla tua classe di visualizzazione.

Supponi di volere che ogni vista mostri la variabile aggiuntiva 'page_title' nel modello. Invece di sovrascrivere il metodo get_context_data ogni volta che definisci la vista, crei un mixin con questo metodo e consenti alle tue opinioni di ereditare da questo mix. Sembra più complicato di quanto non sia in realtà:

# 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
    # ...

La bellezza di questo è che il tuo codice diventa molto più strutturato di quanto non avvenga per le visualizzazioni funzionali. La tua intera logica dietro compiti specifici si trova in un posto e solo in un posto. Inoltre, risparmierai enormi quantità di tempo, specialmente quando hai molte viste che svolgono sempre le stesse attività, tranne che con oggetti diversi



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow