00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Views Basate su Classi

Le views basate su classi (CBV - Class-Based Views) offrono un approccio orientato agli oggetti per gestire le richieste HTTP. Django fornisce numerose viste generiche che implementano i pattern piu comuni, riducendo il codice ripetitivo e favorendo il riuso tramite ereditarieta.

La Classe Base: View

La classe View è la base di tutte le CBV. Implementa metodi corrispondenti ai metodi HTTP:

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

class HomeView(View):
    def get(self, request):
        return HttpResponse("Benvenuto! (GET)")

    def post(self, request):
        return HttpResponse("Dati ricevuti! (POST)")

Per collegare una CBV alle URL, usa il metodo .as_view():

# urls.py
from django.urls import path
from .views import HomeView

urlpatterns = [
    path('', HomeView.as_view(), name='home'),
]

TemplateView

TemplateView renderizza un template senza logica aggiuntiva:

from django.views.generic import TemplateView

class ChiSiamoView(TemplateView):
    template_name = 'chi_siamo.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['titolo'] = 'Chi Siamo'
        context['team'] = ['Alice', 'Bob', 'Carlo']
        return context

Per viste statiche semplici, puoi usarla direttamente nelle URL:

urlpatterns = [
    path('chi-siamo/', TemplateView.as_view(template_name='chi_siamo.html')),
]

ListView

ListView mostra un elenco di oggetti di un modello:

from django.views.generic import ListView
from .models import Articolo

class ArticoloListView(ListView):
    model = Articolo
    template_name = 'blog/lista.html'
    context_object_name = 'articoli'
    ordering = ['-data_pubblicazione']
    paginate_by = 10

    def get_queryset(self):
        queryset = super().get_queryset()
        categoria = self.request.GET.get('categoria')
        if categoria:
            queryset = queryset.filter(categoria__slug=categoria)
        return queryset

Nel template, la lista di oggetti e disponibile con il nome definito in context_object_name:

{% for articolo in articoli %}
    <h2>{{ articolo.titolo }}</h2>
    <p>{{ articolo.contenuto|truncatewords:30 }}</p>
{% endfor %}

DetailView

DetailView mostra il dettaglio di un singolo oggetto:

from django.views.generic import DetailView

class ArticoloDetailView(DetailView):
    model = Articolo
    template_name = 'blog/dettaglio.html'
    context_object_name = 'articolo'
    slug_field = 'slug'
    slug_url_kwarg = 'slug'
# urls.py
urlpatterns = [
    path('<slug:slug>/', ArticoloDetailView.as_view(), name='dettaglio'),
]

CreateView

CreateView gestisce la creazione di nuovi oggetti tramite un form:

from django.views.generic import CreateView
from django.urls import reverse_lazy

class ArticoloCreateView(CreateView):
    model = Articolo
    template_name = 'blog/crea.html'
    fields = ['titolo', 'contenuto', 'categoria']
    success_url = reverse_lazy('blog:lista')

    def form_valid(self, form):
        form.instance.autore = self.request.user
        return super().form_valid(form)

reverse_lazy viene usato al posto di reverse perche le URL potrebbero non essere ancora caricate quando la classe viene definita.

UpdateView

UpdateView gestisce la modifica di un oggetto esistente:

from django.views.generic import UpdateView

class ArticoloUpdateView(UpdateView):
    model = Articolo
    template_name = 'blog/modifica.html'
    fields = ['titolo', 'contenuto', 'categoria']
    success_url = reverse_lazy('blog:lista')

DeleteView

DeleteView gestisce l’eliminazione di un oggetto con conferma:

from django.views.generic import DeleteView

class ArticoloDeleteView(DeleteView):
    model = Articolo
    template_name = 'blog/conferma_elimina.html'
    success_url = reverse_lazy('blog:lista')

Il template di conferma tipicamente contiene un form con metodo POST:

<h2>Sei sicuro di voler eliminare "{{ articolo.titolo }}"?</h2>
<form method="post">
    {% csrf_token %}
    <button type="submit">Elimina</button>
    <a href="{% url 'blog:lista' %}">Annulla</a>
</form>

Mixins

I mixins aggiungono funzionalita alle CBV tramite ereditarieta multipla:

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin

class ArticoloCreateView(LoginRequiredMixin, CreateView):
    model = Articolo
    fields = ['titolo', 'contenuto']
    login_url = '/login/'

class ArticoloUpdateView(UserPassesTestMixin, UpdateView):
    model = Articolo
    fields = ['titolo', 'contenuto']

    def test_func(self):
        articolo = self.get_object()
        return self.request.user == articolo.autore

I mixins piu comuni sono:

  • LoginRequiredMixin: Richiede che l’utente sia autenticato.
  • PermissionRequiredMixin: Richiede permessi specifici.
  • UserPassesTestMixin: Esegue un test personalizzato sull’utente.

Conclusione

Le views basate su classi semplificano lo sviluppo di funzionalita CRUD e viste comuni grazie alle viste generiche di Django. I mixins permettono di comporre comportamenti complessi in modo modulare. Per logica semplice, le views basate su funzioni restano valide, ma per operazioni ripetitive le CBV riducono significativamente la quantita di codice necessario.