Code


Version 2 (modified by paolo <paolo@…>, 8 years ago) (diff)

Added directive for automatic toc generation.

Primo sguardo a Django

Poiché Django è stato sviluppato in un dipartimento di pubblicazione giornalistica in cui le informazioni da pubblicare sono molte e frequenti, si è cercato di semplificare le operazioni legate allo sviluppo Web rendendole veloci e snelle. Questo documento è un'introduzione informale alla stesura di applicazioni Web basate su database realizzate con Django.

L'obiettivo di questo documento è fornire un numero sufficiente di notizie tecniche per rendere comprensibili i principi di funzionamento di Django, senza però voler essere né un tutorial né un reference. Quando sarai pronto per cominciare un progetto affidati alla documentazione che descrive Django con maggior dettaglio.

Progetta il modello

Sebbene sia possibile usare Django senza un database, viene fornito un mapper oggetti-relazionale che consente di descrivere la struttura dei dati dell'applicazione con codice Python.

La sintassi per la modellazione dei dati offre una ricca gamma di possibilità -- oramai sono due anni che viene usata con successo per risolvere problematiche legate alla generazione di schemi di database. Questo è un breve esempio:

class Reporter(models.Model):
    full_name = models.CharField(maxlength=70)

    def __str__(self):
        return self.full_name

class Article(models.Model):
    pub_date = models.DateTimeField()
    headline = models.CharField(maxlength=200)
    article = models.TextField()
    reporter = models.ForeignKey(Reporter)

    def __str__(self):
        return self.headline

Installa il modello

In seguito, quando invocherai l'utility apposita offerta da Django, le tabelle saranno create automaticamente:

manage.py syncdb

Il comando syncdb considera tutti i modelli disponibili e crea le tabelle all'interno del database, per tutte le tabelle non pre-esistenti.

Usa le API a corredo

Grazie alle operazioni che hai appena compiuto, ti viene messo a disposizione un completo insieme di API Python, creato in modo automatico, per consentirti di accedere ai dati della tua applicazione: non è necessaria alcuna generazione di codice:

>>> from mysite.models import Reporter, Article

# Non sono ancora stati inseriti reporter.
>>> Reporter.objects.all()
[]

# Crea un nuovo Reporter.
>>> r = Reporter(full_name='John Smith')

# Salva l'oggetto nel database. save() deve esplicitamente essere invocato.
>>> r.save()

# Ora l'oggetto ha un ID.
>>> r.id
1

# Ora il nuovo reporter è nel database.
>>> Reporter.objects.all()
[John Smith]

# I campi sono rappresentati come attributi dell'oggetto Python.
>>> r.full_name
'John Smith'

# Django offre un insieme di API per effettuare interrogazioni sui dati.
>>> Reporter.objects.get(id=1)
John Smith
>>> Reporter.objects.get(full_name__startswith='John')
John Smith
>>> Reporter.objects.get(full_name__contains='mith')
John Smith
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Reporter does not exist for {'id__exact': 2}

# Crea un articolo.
>>> from datetime import datetime
>>> a = Article(pub_date=datetime.now(), headline='Django is cool',
...     article='Yeah.', reporter=r)
>>> a.save()

# Ora l'articolo è nel database.
>>> Article.objects.all()
[Django is cool]

# Gli oggetti Article incorporano le API per l'accesso agli oggetti Reporter a cui sono associati.
>>> r = a.reporter
>>> r.full_name
'John Smith'

# >Si verifica anche il vice versa: gli oggetti Reporter incorporano le API per l'accesso agli oggetti Article.
>>> r.article_set.all()
[Django is cool]

# Le API seguono le relazioni secondo le tue esigenze, generando
# operazioni di JOIN efficienti al posto tuo, in modo trasparente.
# Il seguente codice trova tutti gli articoli di un reporter il cui nome comincia con "John".
>>> Article.objects.filter(reporter__full_name__startswith="John")
[Django is cool]

# Modifica un oggetto alterandone gli attributi e invocando save().
>>> r.full_name = 'Billy Goat'
>>> r.save()

# Elimina un oggetto tramite delete().
>>> r.delete()

Un'interfaccia di amministrazione dinamica: non solo un'impalcatura, ma l'intera casa

Una volta definiti i modelli, Django può creare automaticamente un'interfaccia amministrativa professionale e pronta per essere usata in produzione -- si tratta di un sito Web che consente agli utenti autenticati di aggiungere, modificare ed eliminare oggetti. Poterla avere è semplice come aggiungere una linea di codice alle classi dei modelli per cui si desidera un'interfaccia di amministrazione:

class Article(models.Model): pub_date = models.DateTimeField()
    headline = models.CharField(maxlength=200)
    article = models.TextField()
    reporter = models.ForeignKey(Reporter)
    class Admin: pass

L'idea di base è che le modifiche al sito vengano effettuate da un gruppo di persone, o da un cliente, o magari semplicemente da te -- senza però l'onere di dover creare l'interfaccia di gestione se lo scopo è semplicemente quello di gestire contenuti.

Un tipico ciclo di vita nella creazione di applicazioni con Django consiste nella realizzazione dei modelli e nel disporre di un sito di amministrazione funzionante nel più breve tempo possibile, in modo che lo staff o i clienti possano cominciare l'inserimento dei dati. Solo in seguito si darà importanza alla parte di presentazione dei dati al pubblico.

Progetta gli URL

Presentare URL puliti ed eleganti è un dettaglio importante in una applicazione Web di elevata qualità. Django favorisce la progettazione di splendidi URL in cui non compaiono informazioni superflue come .php o .asp.

La progettazione degli URL di un'applicazione avviene creando un modulo Python chiamato URLconf. Lo si può pensare come la tabella dei contenuti dell'applicazione e contiene semplici corrispondenze tra maschere di URL (URL patterns) e funzioni Python. Un'altra finalità dei moduli URLconf è tenere separata la gestione degli URL dal codice Python dell'applicazione.

Ecco come potrebbe apparire un URLconf per l'esempio Reporter/Article esposto in precedenza:

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^/articles/(\d{4})/$', 'mysite.views.year_archive'),
    (r'^/articles/(\d{4})/(\d{2})/$', 'mysite.views.month_archive'),
    (r'^/articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.views.article_detail'),
)

Questo codice associa gli URL, espressi come semplici espressioni regolari, a funzioni di callback scritte in Python (chiamate "view"). La "cattura" dei valori specificati assieme agli URL avviene usando parentesi nelle espressioni regolari. Quando un utente richiede una pagina, Django scorre ogni espressione regolare, rispettando l'ordine di presentazione, interrompendo la ricerca non appena viene trovato un URL in grado di soddisfare l'espressione regolare (se non vengono trovate corrispondenze si fa ricorso ad una view speciale di tipo 404). Le espressioni regolari sono compilate in fase di caricamento, perciò il procedimento di invocazione di una funzione in base all'URL richiesto risulta incredibilmente prestazionale.

Quando una delle espressioni regolari corrisponde, Django importa e invoca la view associata, che semplicemente è una funzione Python. Ad ogni view viene passato un oggetto request -- contenente i metadati relativi alla richiesta -- e i valori catturati nell'espressione regolare.

Ad esempio, se un utente dovesse richiede l'URL "/articles/2005/05/39323/", Django invocherebbe la funzione mysite.views.article_detail(request, '2005', '05', '39323').

Scrivi le view

Ogni view ha la responsabilità di restituire un oggetto HttpResponse contenente la pagina di risposta oppure sollevare un'eccezione come Http404. Il resto dei compiti spetta a te.

Generalmente, una view ottiene i dati definiti dai parametri, carica un template (un modello della pagina che verrà restituita in seguito ad una richiesta) e popola il template con i dati ottenuti. La view year_archive potrebbe verosimilmente essere qualcosa di questo tipo:

def year_archive(request, year):
    a_list = Article.objects.filter(pub_date__year=year)
    return render_to_response('news/year_archive.html', {'year': year, 'article_list': a_list})

Il codice dell'esempio usa il meccanismo di gestione dei template offerto da Django, che pur esponendo funzionalità avanzate risulta sufficientemente semplice per poter essere usato anche da chi non è un programmatori.

Progetta i template

Nell'esempio, la vista year_archive carica il template news/year_archive.html.

Django minimizza le ridondanze tra i modelli di pagina implementando un percorso di ricerca dei template. Nelle impostazioni di configurazione puoi specificare una lista di directory dedicate ad ospitare i template. Se si cerca un template non presente nella prima directory, viene cercato nella seguente, e così via.

Ipotizziamo che il template news/article_detail.html venga trovato. Potrebbe verosimilmente apparire così:

{% extends "base.html" %}

{% block title %}Articoli del {{ year }}{% endblock %}

{% block content %}
<h1>Articoli del {{ year }}</h1>

{% for article in article_list %}
<p>{{ article.headline }}</p>
<p>By {{ article.reporter.full_name }}</p>
<p>Pubblicato in data {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}

Le variabili sono circondate da coppie di parentesi graffe. {{article.headline }} significa "Restituisci il valore dell'attributo headline di article". Le parentesi graffe non vengono utilizzate esclusivamente per il lookup degli attributi, ma anche per ottenere i valori corrispondenti a chiavi di dizionario, per il lookup basato su indici o per richiamare funzioni.

Nota come le "pipe" (il carattere "|") in stile Unix vengono utilizzate in {{ article.pub_date|date:"F j, Y" }}. Questo particolare costrutto è un filtro di template, e viene usato per filtrare il contenuto di una variabile. In questo caso, il filtro date formatta un oggetto datetime di Python nel formato specificato (come descritto nella funzione date di PHP; ebbene sì, c'è una buona idea in PHP).

Puoi concatenare un numero arbitrario di filtri, puoi scrivere filtri personalizzati e, se hai la necessità di eseguire codice Python nel template in modo trasparente, puoi anche personalizzare i tag di template.

Per finire, Django adotta il concetto di "ereditarietà dei tempate": è ciò che avviene in {% extends "base.html" %}. Significa "Prima carica il template con nome 'base', dove sono definiti blocchi vuoti, poi riempi questi blocchi con altri blocchi". In sostanza, la ridondanza nei template viene drasticamente ridotta: ogni template deve definire solamente gli elementi che lo caratterizzano rendendolo unico.

Il template "base.html" potrebbe essere:

<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <img src="sitelogo.gif" alt="Logo" />
    {% block content %}{% endblock %}
</body>
</html>

Evitando spiegazioni prolisse, questo template definisce l'aspetto comune del sito (il look-and-feel) con il logo, emette a disposizione aree vuote che saranno riempite da template figli. Il restyling di un sito si riduce al ritocco di un singolo file -- il template base.

L'ereditarietà dei template consente anche di creare differenti versioni di un sito usando template di base diversi che condividono gli stessi template figli. Gli autori di Django hanno usato questa tecnica per creare edizioni di siti adatte alla visualizzazione su telefoni cellulari, semplicemente creando un nuovo template di base.

Sappi che non sei obbligato ad usare il sistema di template di Django, se ne preferisci altri. Nonostante esso sia particolarmente ben integrato nel framework, nulla ti forza ad usarlo. Per lo stesso motivo non ti è nemmeno imposto l'obbligo di usare le API di Django per l'interfacciamento ai database. Puoi usare un altro sistema di astrazione per database, puoi leggere file XML, file su disco o fare qualsiasi altra cosa sia nelle tue intenzioni. Ogni frammento di Django -- i modelli, le view, i template -- è indipendente dal seguente.

Questo è solo un assaggio

Il contenuto di questo documento è soltanto una rapida panoramica di quelle che sono le funzionalità di Django. Alcune altre caratteristiche, ancora più utili, sono:

  • Un sistema di caching che si integra con svariati backend, tra cui memcached.
  • Un sistema di syndication che rende la creazione di feed RSS e Atom un'operazione tanto semplice da essere paragonabile alla scrittura di una piccola classe Python.
  • Funzionalità di amministrazione generate automaticamente -- in questa introduzione non si è andati oltre la superficie.

Ora per te, i prossimi passi logici saranno scaricare Django, leggere il tutorial e diventare parte della comunità. Grazie per l'interesse mostrato!