Upload di File
L’upload di file e’ una funzionalita’ comune nelle applicazioni web. Django fornisce strumenti integrati per gestire l’upload, la validazione e il salvataggio dei file in modo semplice e sicuro.
Configurazione di Base
Prima di gestire i file caricati, e’ necessario configurare le directory dove Django salvera’ i file media.
# settings.py
import os
# Directory fisica dove vengono salvati i file
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# URL pubblica per accedere ai file media
MEDIA_URL = '/media/'
Per servire i file media durante lo sviluppo, aggiungi la configurazione URL:
# urls.py (progetto principale)
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... le tue URL ...
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
FileField e ImageField
Django offre due campi specifici per i modelli: FileField per file generici e ImageField per le immagini (che richiede la libreria Pillow).
from django.db import models
class Documento(models.Model):
titolo = models.CharField(max_length=200)
file = models.FileField(upload_to='documenti/')
caricato_il = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.titolo
class Profilo(models.Model):
utente = models.OneToOneField('auth.User', on_delete=models.CASCADE)
avatar = models.ImageField(upload_to='avatar/', blank=True, null=True)
curriculum = models.FileField(upload_to='cv/%Y/%m/', blank=True)
Il parametro upload_to specifica la sottodirectory all’interno di MEDIA_ROOT. Puoi usare formati di data come %Y/%m/ per organizzare i file per anno e mese.
Upload Dinamico con Funzione
Puoi usare una funzione per determinare dinamicamente il percorso di upload:
def percorso_upload_utente(instance, filename):
return f'utenti/{instance.utente.id}/{filename}'
class Profilo(models.Model):
utente = models.OneToOneField('auth.User', on_delete=models.CASCADE)
avatar = models.ImageField(upload_to=percorso_upload_utente)
Gestione dell’Upload nelle View
Per gestire l’upload dei file nelle view, si accede ai file tramite request.FILES. E’ fondamentale che il form HTML abbia l’attributo enctype="multipart/form-data".
# forms.py
from django import forms
from .models import Documento
class DocumentoForm(forms.ModelForm):
class Meta:
model = Documento
fields = ['titolo', 'file']
# views.py
from django.shortcuts import render, redirect
from .forms import DocumentoForm
def carica_documento(request):
if request.method == 'POST':
form = DocumentoForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('lista_documenti')
else:
form = DocumentoForm()
return render(request, 'carica_documento.html', {'form': form})
Il template corrispondente deve includere enctype:
# carica_documento.html
# <form method="post" enctype="multipart/form-data">
# {% csrf_token %}
# {{ form.as_p }}
# <button type="submit">Carica</button>
# </form>
Validazione dei File
E’ importante validare i file caricati per sicurezza e per rispettare le specifiche dell’applicazione.
from django.core.exceptions import ValidationError
def valida_dimensione_file(file):
limite_mb = 5
if file.size > limite_mb * 1024 * 1024:
raise ValidationError(f'Il file non puo superare {limite_mb} MB.')
def valida_estensione(file):
estensioni_valide = ['.pdf', '.doc', '.docx']
import os
ext = os.path.splitext(file.name)[1].lower()
if ext not in estensioni_valide:
raise ValidationError('Formato file non supportato.')
class Documento(models.Model):
titolo = models.CharField(max_length=200)
file = models.FileField(
upload_to='documenti/',
validators=[valida_dimensione_file, valida_estensione]
)
Storage Backend
Django utilizza un sistema di storage per gestire il salvataggio dei file. Il backend predefinito e’ FileSystemStorage, che salva i file sul disco locale.
from django.core.files.storage import FileSystemStorage
# Storage personalizzato
storage_privato = FileSystemStorage(
location='/percorso/file_privati/',
base_url='/privato/'
)
class DocumentoPrivato(models.Model):
file = models.FileField(storage=storage_privato)
Django 5.x supporta anche la configurazione globale dello storage tramite STORAGES:
# settings.py
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
},
}
Conclusione
La gestione dell’upload di file in Django e’ un processo ben strutturato che copre dalla configurazione iniziale con MEDIA_ROOT e MEDIA_URL, alla definizione dei campi nei modelli con FileField e ImageField, fino alla validazione e al salvataggio tramite storage backend. Seguire le buone pratiche di validazione e sicurezza garantisce un sistema di upload robusto e affidabile.