22 marzo 2007

Esperimenti con Django

Dopo aver letto e copiato pari pari il tutorial di Django, ottenendo una simpatica applicazione web per gestire sondaggi, ho deciso di provare a fare qualcosa da solo.
Cercherò di sviluppare una webapp per gestire e visualizzare un guestbook.
Per prima cosa occore creare l'applicazione con il comando

python manage.py startapp guestbook
Questo comando genera una directory di nome guestbook, con dentro 3 file: __init__.py, models.py, views.py.
Ora bisogna creare le classi che comporranno l'applicazione. Per un semplice guestbook, bastano due classi: Guestbook e Messaggi. Creiamole editando il file models.py
from django.db import models

class Guestbook(models.Model):
nome = models.CharField(maxlength=200)
data_creazione = models.DateTimeField('data di creazione')

class Messaggi(models.Model):
guestbook = models.ForeignKey(Guestbook)
messaggio = models.TextField()
autore = models.CharField(maxlength=50)
data = models.DateTimeField('data messaggio')
email = CharField(maxlength=50)
Ora dobbiamo dire a Django che il guetbook fa parte del progetto corrente, editando il file settigs.py e aggiungendo 'mysite.guestbook' a INSTALLED_APPS.
Ora Django può creare le tabelle su db che rappresentino gli oggetti appena definiti. Il comando python manage.py sql guestbook ci mostra le query che verrano lanciate per fare ciò:

BEGIN;
CREATE TABLE `guestbook_messaggi` (

`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`guestbook_id` integer NOT NULL,
`messaggio` longtext NOT NULL,
`autore` varchar(50) NOT NULL,
`data` datetime NOT NULL,
`email` varchar(50) NOT NULL
);
CREATE TABLE `guestbook_guestbook` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`nome` varchar(200) NOT NULL,
`data_creazione` datetime NOT NULL
);
ALTER TABLE `guestbook_messaggi` ADD CONSTRAINT guestbook_id_referencing_guestbook_guestbook_id FOREIGN KEY (`guestbook_id`) REFERENCES `guestbook_guestbook` (`id`);
COMMIT;
Per fargliele eseguire, si usa il comando python manage.py syncdb, che sicronizza il database con gli oggetti definiti.
Django aggiunge automaticamente un campo id autoincrementante come chiave primaria delle tabelle, e anche i campi che sono chiavi esterne, specificati nella definizione dell'oggetto con models.ForeignKey(tabellareferenziata).

Ora abbiamo tutto pronto per iniziare a sviluppare il guestbook, ma prima utilizziamo una delle caratteristiche più interessanti di Django, la creazione automatica del backoffice per gestire le nostre tabelle.
Se nel file settings.py, all'interno di INSTALLED_APPS, è presente l'applicazione django.contrib.admin, allora il backoffice è già attivo e funzionate, dobbiamo solo dire ai nostri oggetti che dovranno apparirvi.
Per fare ciò, dobbiamo creare una sottoclasse di Guestbook e di Messaggi, di nome Admin, editando il file models.py:
class Guestbook(models.Model):
# i vari campi
class Admin:
pass
class Messaggi(models.Model):
# i vari campi
class Admin:
pass
Salviamo, puntiamo il browser su http://www.miosito.com/admin/ e vedremo l'interfaccia del backoffice.
Per ogni oggetto, ci viene data la possibilità di crearne di nuovi, modificarli o di eliminarli.
E' possibile raffinare l'aspetto e la funzionalità di questo backoffice modificando le sottoclassi Admin degli oggetti, ma già la versione standard è completissima e perfettamente usabile.

Ora possiamo iniziare a creare le funzionalità del guestbook vero e proprio.
Per prima cosa, editiamo il file urls.py, in modo che somigli a qualcosa del genere:
urlpatterns = patterns(
(r'^guestbook/$', 'mysite.polls.views.index'),
(r'^guestbook/(?P\d+)/$', 'mysite.guestbook.views.showmessages'),
)
Django usa un sistema di espressioni regolari per associare gli url alle fuzionalità di un applicazione: nel nostro caso, quando viene chiamata un url del tipo http://www.miosito.com/guestbook, il server caricherà la view contenuta in mysite.polls.views.index. Cos'è una view? E' un tipo di pagina, che serve ad una specifica funzione e ha un suo template.
Le view si definiscono nel file views.py.
Per prima cosa, creiamo la view che verrà caricata come index:
from django.template import Context, loader
from mysite.guestbook.models import Guestbook
from django.http import HttpResponse

def index(request):
gb = Guestbook.objects.all().order_by('-data_creazione')
t = loader.get_template('guestbook/index.html')
c = Context({
'gb': gb
})
return HttpResponse(t.render(c))
La view index estrae tutti gli oggetti Guestbook dal db, in ordine discendente rispetto alla data di creazione, carica il template, crea un context, ovvero un dizionario che mappa nomi di variabili del template su nomi di oggetti, renderizza il template con il context e restituisce un oggetto HttpResponse.

Ora manca solo il template, creiamolo:


[html]
[body]
[center]Guestbook[/center]
{% if gb %}
[ul]
{% for g in gb %}
[li][a href="{{g.id}}"]{{g.nome}}[/a][/li]
[/ul]
{% endfor %}
{% else %}
[center]Nessun guestbook presente[/center]
{% endif %}
[/body]
[/html]
(Ho messo le quadre al posto di <> se non blogger schizza.)
Questo template riceve l'oggetto gb dalla view, e per ogni oggetto di tipo Guestbook dentro a gb stampa un link con il nome del guestbook.

Se ora apriamo http://www.miosito.com/guestbook, vedremo l'elenco dei guestbook.

Ora dobbiamo creare la view che visualizzi l'elenco dei messaggi di un certo guestbook:

def showmessages(request, guestbook_id):
g = Guestbook.objects.get(pk=guestbook_id)
m = Messaggi.objects.filter(guestbook=guestbook_id).order_by('-data')
t = loader.get_template('guestbook/messaggi.html')
c = Context({
'm': m,
'g': g
})
return HttpResponse(t.render(c))

e il template messaggi.html:

[html]
[style]
h3 {
font-size: 14px;
font-family: verdana;
font-weight: bold;
}
h1 {
font-size: 16px;
font-family: verdana;
font-weight: bold;
}
p {
font-size: 10px;
font-family: verdana;
font-weight: normal;
border: 1px solid;
width: 200px;
}
[/style]
[body]
[center]
[h1]{{ g.nome }}[/h1]
[br]
{% for mex in m %}
[div]
[h3]{{mex.autore}} {{mex.data}} {{mex.email}}[/h3]
[p]{{mex.messaggio}}[/p]
[/div]
{% endfor %}
[/center]
[/body]
[/html]

Ecco fatto.
Ora puntiamo il browser su http://www.miosito.com/guestbook/1/ e vedremo l'elenco dei messaggi inseriti nel nostro primo guestbook!

Prossimamente, aggiungerò un form per inserire nuovi messaggi, per imparare a gestire il passaggio di dati in POST.

2 commenti:

Anonimo ha detto...

perfetto finalmente qualche tutorial in italiano :)
ce ne sono altri?

MarcoS82 ha detto...

Ciao, ottimo tutorial! Solo una precisazione: ora con django non c'è più bisogno di fare:

t = loader.get_template('guestbook/index.html')
c = Context({
'gb': gb
})
return HttpResponse(t.render(c))


basta utilizzare django.shortcuts.render_to_response

quindi def index(request):potrà essere scritta come:

def index(request):
gb = Guestbook.objects.all().order_by('-data_creazione')
return render_to_response('guestbook/index.html', {'gb': gb})