Tutorial Django
Impara Django da zero: installa il framework, crea modelli, viste, template, esegui le migrazioni e avvia un'app web funzionante passo dopo passo.
Django è un framework web Python di alto livello che consente di creare applicazioni web sicure e scalabili rapidamente. Segue il pattern architetturale Model-Template-View (MTV) — strettamente correlato all'MVC — e include un ORM, un'interfaccia amministrativa, routing degli URL, autenticazione e molto altro già integrati. La filosofia "batteries-included" di Django significa che puoi concentrarti sulla logica della tua applicazione invece di assemblare l'infrastruttura.
Questo tutorial illustra i passaggi essenziali: installare Django in un ambiente virtuale, creare un progetto e un'app, definire i modelli, scrivere le viste, costruire i template, eseguire le migrazioni del database e verificare tutto nel browser.
Perché Usare Django
Batteries Included
Django include un pannello amministrativo integrato, autenticazione degli utenti, gestione dei form, un ORM, supporto alla cache e utilità per l'internazionalizzazione. Non è necessario cercare pacchetti di terze parti per coprire queste funzionalità di base.
Sicurezza per Impostazione Predefinita
Django si protegge dagli attacchi SQL injection utilizzando query parametrizzate attraverso il suo ORM. Fornisce anche protezione integrata contro Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF) e clickjacking. La chiave segreta, la modalità DEBUG e le impostazioni ALLOWED_HOSTS riducono ulteriormente la superficie di attacco.
Scalabilità
Django alimenta siti ad alto traffico tra cui Instagram e Disqus. Il suo framework di caching si integra con Memcached e Redis, e l'ORM supporta il connection pooling del database. Puoi scalare verticalmente o orizzontalmente senza modificare il codice dell'applicazione.
Ecosistema Vasto
L'indice dei pacchetti di Django elenca migliaia di app di terze parti — API REST (djangorestframework), gestione delle immagini, gateway di pagamento e altro ancora. La stabilità del framework e il lungo ciclo di rilascio garantiscono che questi pacchetti siano attivamente mantenuti.
Come Funziona il Pattern MTV di Django
| Livello | Termine Django | Responsabilità |
|---|---|---|
| Dati | Model | Classe Python che mappa a una tabella del database |
| Presentazione | Template | File HTML con segnaposto {{ variable }} |
| Logica | View | Funzione Python (o classe) che legge i dati e restituisce una risposta |
Il dispatcher degli URL (urls.py) mappa i percorsi delle richieste in arrivo alla vista corretta. La vista interroga i modelli, poi passa i dati a un template. L'HTML renderizzato viene restituito al browser.
Configurare un Ambiente Virtuale
Isola sempre i progetti Django in un ambiente virtuale in modo che le dipendenze non entrino in conflitto tra i progetti.
# Create and activate a virtual environment
python -m venv venv
source venv/bin/activate # macOS / Linux
venv\Scripts\activate # WindowsDopo l'attivazione il prompt mostra (venv). Ogni pip install da questo momento influisce solo su questo ambiente.
Installare Django
Con l'ambiente virtuale attivo, installa Django usando pip:
pip install djangoVerifica l'installazione:
python -m django --versionDjango stampa una stringa di versione come 5.1.4.
Creare un Progetto Django
Un progetto è il contenitore di livello superiore per l'intero sito. Creane uno con:
django-admin startproject mysite
cd mysiteQuesto genera la seguente struttura:
mysite/
├── manage.py # Command-line utility for this project
└── mysite/
├── __init__.py
├── settings.py # Project configuration (database, installed apps, …)
├── urls.py # Root URL dispatcher
├── asgi.py # ASGI entry point
└── wsgi.py # WSGI entry pointmanage.py è il tuo strumento principale per eseguire comandi come avviare il server di sviluppo, creare migrazioni e creare un superutente. La cartella interna mysite/ è il pacchetto Python per il progetto stesso.
Creare un'App Django
Un progetto può contenere più app — moduli autonomi, ognuno responsabile di un'area funzionale. Crea un'app blog:
python manage.py startapp blogRegistrala in modo che Django possa trovare i suoi modelli, template e file statici. Apri mysite/settings.py e aggiungi 'blog' a INSTALLED_APPS:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog', # <-- add this line
]La directory dell'app si presenta così dopo la creazione:
blog/
├── __init__.py
├── admin.py # Register models with the admin interface
├── apps.py # App configuration
├── migrations/ # Auto-generated migration files
│ └── __init__.py
├── models.py # Database models
├── tests.py
└── views.py # View functionsDefinire i Modelli
Un modello è una classe Python che estende django.db.models.Model. Ogni attributo della classe mappa a una colonna del database. L'ORM di Django traduce il tuo codice Python in SQL e gestisce tutte le interazioni con il database.
Apri blog/models.py e definisci un modello Post:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
date_posted = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Meta:
ordering = ['-date_posted'] # Newest posts firstTipi di campo chiave utilizzati qui:
| Campo | Scopo |
|---|---|
CharField(max_length=N) | Testo breve con lunghezza massima |
TextField() | Testo a lunghezza illimitata |
ForeignKey(…, on_delete=CASCADE) | Relazione molti-a-uno; elimina i post quando il loro autore viene eliminato |
DateTimeField(auto_now_add=True) | Impostato una volta alla creazione del record |
DateTimeField(auto_now=True) | Aggiornato ogni volta che il record viene salvato |
Il metodo __str__ controlla come l'oggetto viene visualizzato nel pannello amministrativo e nella shell Python.
Eseguire le Migrazioni
Dopo aver definito o modificato i modelli devi creare e applicare le migrazioni — istruzioni versionabili che aggiornano lo schema del database.
# Generate a new migration file from your model changes
python manage.py makemigrations
# Apply all pending migrations to the database
python manage.py migrateVedrai un output come:
Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model Post
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying blog.0001_initial... OKEsegui migrate ogni volta che aggiungi, rimuovi o modifichi i campi del modello. Non modificare mai i file di migrazione a mano a meno che tu non capisca appieno il loro SQL.
Usare il Pannello Amministrativo di Django
L'interfaccia amministrativa integrata ti consente di creare, leggere, aggiornare ed eliminare record attraverso un browser — senza bisogno di un'UI personalizzata. Registra il modello Post in blog/admin.py:
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'date_posted')
list_filter = ('date_posted', 'author')
search_fields = ('title', 'content')Crea un account superutente per poter accedere:
python manage.py createsuperuserDjango chiede un nome utente, un'email e una password. Poi avvia il server di sviluppo e visita http://127.0.0.1:8000/admin/:
python manage.py runserverAccedi con le credenziali del superutente e vedrai il modello Posts elencato nella sezione "Blog".
Scrivere le Viste
Una vista è una funzione Python (o classe) che riceve una richiesta HTTP e restituisce una risposta HTTP. Apri blog/views.py:
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
"""Display all published posts, newest first."""
posts = Post.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
"""Display a single post by primary key."""
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})get_object_or_404 è una comoda scorciatoia: recupera l'oggetto dal database o restituisce automaticamente una risposta 404 se non esiste. Il terzo argomento di render è un dizionario di contesto — le sue chiavi diventano variabili di template.
Creare i Template
I template sono file HTML che contengono i tag del Django Template Language (DTL). Crea la struttura di directory:
blog/
└── templates/
└── blog/
├── base.html
├── post_list.html
└── post_detail.htmlblog/templates/blog/base.html — un layout condiviso:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}My Blog{% endblock %}</title>
</head>
<body>
<header><h1>My Blog</h1></header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
blog/templates/blog/post_list.html — la pagina elenco:
{% extends "blog/base.html" %}
{% block title %}All Posts{% endblock %}
{% block content %}
{% for post in posts %}
<article>
<h2><a href="/blog/{{ post.pk }}/">{{ post.title }}</a></h2>
<p>By {{ post.author }} on {{ post.date_posted|date:"N j, Y" }}</p>
<p>{{ post.content|truncatewords:30 }}</p>
</article>
{% empty %}
<p>No posts yet.</p>
{% endfor %}
{% endblock %}
blog/templates/blog/post_detail.html — la pagina dettaglio:
{% extends "blog/base.html" %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<h2>{{ post.title }}</h2>
<p>By {{ post.author }} on {{ post.date_posted|date:"N j, Y" }}</p>
<div>{{ post.content }}</div>
<a href="/">Back to all posts</a>
{% endblock %}
Funzionalità DTL chiave utilizzate sopra:
| Tag / Filtro | Cosa fa |
|---|---|
{% extends "…" %} | Eredita da un template base |
{% block name %} | Definisce una sezione sostituibile |
{{ variable }} | Restituisce un valore (HTML-escaped automaticamente) |
{% for … %} / {% empty %} | Ciclo con fallback per liste vuote |
|date:"N j, Y" | Formatta un valore datetime |
|truncatewords:30 | Accorcia il testo a 30 parole |
Configurare gli URL
La configurazione degli URL mappa i percorsi delle richieste alle funzioni di vista.
blog/urls.py — crea questo file nella directory blog:
from django.urls import path
from . import views
app_name = 'blog' # Enables namespaced URL reversing
urlpatterns = [
path('', views.post_list, name='post_list'),
path('<int:pk>/', views.post_detail, name='post_detail'),
]mysite/urls.py — includi gli URL dell'app nella radice del progetto:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls', namespace='blog')),
path('', include('blog.urls', namespace='blog_root')),
]Il convertitore di percorso <int:pk> cattura un intero dall'URL e lo passa come argomento keyword pk a post_detail.
Verificare il Flusso Completo
Avvia il server di sviluppo:
python manage.py runserverPoi apri http://127.0.0.1:8000/ nel tuo browser. Se non esistono ancora post, il template mostra "No posts yet." Accedi a http://127.0.0.1:8000/admin/ e aggiungi un post. Aggiorna la home page — il post appare immediatamente.
Il ciclo di vita della richiesta per la home page è:
- Il browser invia
GET / - Il dispatcher degli URL di Django abbina
''e chiamapost_list post_listinterrogaPost.objects.all()(si traduce inSELECT * FROM blog_post ORDER BY date_posted DESC)- Django renderizza
post_list.html, inserendo i post nel template - L'HTML renderizzato viene restituito al browser
Cheatsheet delle Query ORM di Django
L'ORM ti permette di costruire query SQL usando catene di metodi Python. Capire le ricerche più comuni fa risparmiare molto tempo:
# All posts
Post.objects.all()
# Posts by a specific author
Post.objects.filter(author__username='alice')
# Posts containing a word in the title (case-insensitive)
Post.objects.filter(title__icontains='django')
# The five most recent posts
Post.objects.order_by('-date_posted')[:5]
# Count posts
Post.objects.count()
# Get one object (raises DoesNotExist if not found)
Post.objects.get(pk=1)
# Exclude posts by a specific author
Post.objects.exclude(author__username='alice')Ognuno di questi genera una query SQL solo quando il queryset viene valutato (iterato, sezionato o convertito in una lista). Questo si chiama lazy evaluation e mantiene al minimo le chiamate inutili al database.
Riepilogo della Struttura del Progetto
Dopo aver completato questo tutorial, la struttura del progetto è la seguente:
mysite/
├── manage.py
├── mysite/
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── blog/
├── admin.py
├── migrations/
│ └── 0001_initial.py
├── models.py
├── templates/
│ └── blog/
│ ├── base.html
│ ├── post_list.html
│ └── post_detail.html
├── urls.py
└── views.pyErrori Comuni
Dimenticare di registrare l'app. Se 'blog' manca da INSTALLED_APPS, Django non troverà i suoi modelli o template e makemigrations non produrrà output per quell'app.
Saltare migrate dopo makemigrations. Eseguire solo makemigrations crea il file di migrazione ma non tocca il database. Segui sempre con migrate.
Errori di template non trovato. Django cerca i template all'interno della directory templates/ di ciascuna app. La cartella blog/ aggiuntiva all'interno di templates/ (templates/blog/post_list.html) è una convenzione che previene le collisioni di nomi tra le app — non saltarla.
DEBUG = True in produzione. Il server di sviluppo e DEBUG = True espongono i traceback a chiunque. Imposta DEBUG = False e configura ALLOWED_HOSTS prima del deploy.
Prossimi Passi
- Moduli Python — comprendi come il sistema di moduli di Python è alla base della struttura di import di Django.
- Python PIP — gestisci Django e le sue dipendenze.
- Ambienti Virtuali Python — mantieni ogni progetto Django isolato.
- MySQL con Python — sostituisci SQLite con un database adatto alla produzione.
- MongoDB con Python — usa un backend NoSQL con Django.
La documentazione ufficiale di Django su docs.djangoproject.com copre le viste basate su classi, i form, l'autenticazione, le API REST con Django REST Framework e il deploy in produzione — tutti passi successivi naturali una volta che hai familiarità con le basi trattate qui.