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.