ModelForm
I ModelForm sono una delle funzionalita piu potenti di Django. Permettono di generare automaticamente un form a partire da un modello del database, eliminando la duplicazione del codice e semplificando la creazione e lâaggiornamento degli oggetti.
Definire un ModelForm
Un ModelForm si crea definendo una classe interna Meta che specifica il modello e i campi da includere:
# models.py
from django.db import models
class Prodotto(models.Model):
nome = models.CharField(max_length=200)
descrizione = models.TextField()
prezzo = models.DecimalField(max_digits=10, decimal_places=2)
disponibile = models.BooleanField(default=True)
data_creazione = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.nome
# forms.py
from django import forms
from .models import Prodotto
class ProdottoForm(forms.ModelForm):
class Meta:
model = Prodotto
fields = ['nome', 'descrizione', 'prezzo', 'disponibile']
Opzioni della Classe Meta
La classe Meta offre diverse opzioni per controllare il comportamento del form:
class ProdottoForm(forms.ModelForm):
class Meta:
model = Prodotto
fields = ['nome', 'descrizione', 'prezzo', 'disponibile']
# oppure: fields = '__all__' per includere tutti i campi
# oppure: exclude = ['data_creazione'] per escluderne alcuni
labels = {
'nome': 'Nome del Prodotto',
'prezzo': 'Prezzo (EUR)',
}
widgets = {
'descrizione': forms.Textarea(attrs={
'rows': 4,
'placeholder': 'Descrivi il prodotto...'
}),
'prezzo': forms.NumberInput(attrs={'step': '0.01'}),
}
help_texts = {
'nome': 'Inserisci il nome completo del prodotto.',
}
error_messages = {
'nome': {
'max_length': 'Il nome non puo superare i 200 caratteri.',
},
}
Creare un Oggetto con ModelForm
Per creare un nuovo oggetto nel database usando un ModelForm:
# views.py
from django.shortcuts import render, redirect
from .forms import ProdottoForm
def crea_prodotto(request):
if request.method == 'POST':
form = ProdottoForm(request.POST)
if form.is_valid():
prodotto = form.save()
return redirect('dettaglio_prodotto', pk=prodotto.pk)
else:
form = ProdottoForm()
return render(request, 'crea_prodotto.html', {'form': form})
Il metodo save() crea automaticamente lâoggetto nel database e lo restituisce.
Aggiornare un Oggetto Esistente
Per modificare un oggetto esistente, passa lâistanza al form con il parametro instance:
from django.shortcuts import get_object_or_404
def modifica_prodotto(request, pk):
prodotto = get_object_or_404(Prodotto, pk=pk)
if request.method == 'POST':
form = ProdottoForm(request.POST, instance=prodotto)
if form.is_valid():
form.save()
return redirect('dettaglio_prodotto', pk=prodotto.pk)
else:
form = ProdottoForm(instance=prodotto)
return render(request, 'modifica_prodotto.html', {'form': form})
Salvare con commit=False
Se hai bisogno di modificare lâoggetto prima di salvarlo nel database, usa commit=False:
def crea_prodotto(request):
if request.method == 'POST':
form = ProdottoForm(request.POST)
if form.is_valid():
prodotto = form.save(commit=False)
prodotto.creato_da = request.user
prodotto.save()
return redirect('lista_prodotti')
else:
form = ProdottoForm()
return render(request, 'crea_prodotto.html', {'form': form})
ModelForm con Class-Based Views
Django 5.x integra perfettamente i ModelForm con le class-based views:
from django.views.generic.edit import CreateView, UpdateView
from .models import Prodotto
from .forms import ProdottoForm
class CreaProdottoView(CreateView):
model = Prodotto
form_class = ProdottoForm
template_name = 'crea_prodotto.html'
success_url = '/prodotti/'
def form_valid(self, form):
form.instance.creato_da = self.request.user
return super().form_valid(form)
class ModificaProdottoView(UpdateView):
model = Prodotto
form_class = ProdottoForm
template_name = 'modifica_prodotto.html'
success_url = '/prodotti/'
Conclusione
I ModelForm semplificano enormemente il lavoro con i form in Django, collegando direttamente il form al modello del database. Grazie a opzioni come widgets, labels e save(commit=False), offrono grande flessibilita mantenendo il codice pulito e conciso. Sono la scelta ideale ogni volta che il form corrisponde a un modello del database.