Django parte3

Avevamo lasciato la descrizione delle voci di settaggio del file settings.py, determina le

opzioni per tutte le applicazioni del progetto. la prima che troviamo è

DEBUG = True

Lasciamola così in ambiente di sviluppo ,ci sarà molto utile per trovare eventuali errori.

Va da sè ,che in produzione verrà messa a False.

TEMPLATE_DEBUG = DEBUG

Il debug nei templates ,così come è impostato ,ovvio che è true,in conseguenza del

DEBUG sopra. Lasciamo così,stesso discorso di sopra.

ADMINS =(

#’ tuo nome’, ‘tua email’

)

Questa tupla serve nel caso DEBUG = False,vi verrà inviata un email con eventuali

errori. Comunque di default è commentata ,e la lasciamo così dato che il DEBUG = True

,quindi non avrebbe senso impostarla.

DATABASES= { }

Questa voce è molto importante ,nel caso andiamo a creare un applicazione appena più

elaborata.Infatti possiamo fare anche senza ,infatti una volta creato nel file urls.py

una mappatura qualsiasi ,nessuno ci vieta che  nel file views.py e qui attraverso il

metodo corrispondente ,potremmo scrivere tutto quello che vogliamo ,d’altronde

potremmo importare qualsiasi modulo python,anche per lavorare con i database

( ovvio senza l ORM di Django ).Dovremmo a questo punto però fare a meno di tutte

le semplificazioni delle sue query specifiche.Comunque un applicazione Django la si

puo fare anche senza databases.Al momento che i dati sono però parecchi ,l’ indubbia

utilità di un database dove memorizzarli ,e di un liguaggio di query generale per qualsiasi

base di dati,mi sembra sia ineccepibile.Quindi per farlo bisogna impostare qui i suoi

parametri di utilizzo. Queta opzione è cambiata dalla versione 1.2. mentre prima

avevamo una costante stringa per ogni parametro del database da usare

(DATABASE_ENGINE, DATABASE_USER, DATABASE_HOST ecc. )

dalla 1.2 la voce è diventata un dizionario { } ,e per la sua sintassi ogni voce puo

essere a sua volta un altro dizionario (una sorta di array bidimensionale ), che contiene

una voce con il corrispondente valore.Nel mio esempio è così impostata :

DATABASES = {
‘default': {

ENGINE‘: ‘django.db.backends.mysql’,

NAME‘: ‘django_db7′,

USER‘: ‘root’,

PASSWORD‘: ‘  ‘,

HOST‘: ‘  ‘,

PORT‘: ‘  ‘,

}

, # ATTENZIONE a questa virgola ,tra 2 voci del dizionario essa è necessaria,

#mi ha fatto penare non poco.

‘data1′: {

ENGINE‘: ‘django.db.backends.mysql’,

NAME‘: ‘django_db8′,

USER‘: ‘nome_user’,

PASSWORD‘: ‘password’,

HOST’: ‘www.example.com’,

OPTIONS‘: {

‘read_default_file': ‘/etc/my.cnf’,

},

PORT‘: ”,

}

}

Le varie opzioni sono molto ben commentate nel file stesso,io mi limiterò a

spiegazioni mancanti o non ben esposte.Intanto volgio spiegarvi perchè le voci nel

dizionario sopra sono 2 ‘ALIAS’ differenti (default e data1,dico ALIAS perchè

saranno questi che , sia nei comandi da shell tipo manage.py e

django-admin.py ,oppure nell sql di ORM , indicheranno il database a cui

fare riferimento.‘default’ indica appunto quello principale ,e sempre obbligatorio

indicare ,nel casi ci serva solo uno ,sara proprio questo l’ ALIAS da usare.Il resto

dei parametri vanno in base al tipo di Database usato,al parametro ENGINE , va

aggiunto il tipo di databse al path ‘ django.db.backends ‘ gia presente di

default.Le altro vanno settate in base al vostro server di db usato.Si puo usare

anche sqlite3.La seconda voce dell esempio sopra è l’ alias data1,si tratta sempre

di un server MySQL , ma mentre all’ alias default il settaggio è piuttosto semplice ,

dato che si tratta di un server in localhost ,con impostazioni di base

( user =root , password = ‘ ‘ , port=3306 ).Il secondo alias ( data1 )non gira su

localhost ,ma su di un server raggiungibile da script remoti

(localhost si usa per ragioni di sicurezza ,infatti solo uno script locale puo collegarsi

ad un database che gira con questo server.Comunque il nostro caso serve solo come

test,non è necessario)in questo caso il settaggio delle opzioni

cambia,abbiamo infatti la voce OPTIONS che ci indica il path fisico del file

/etc/my.cnf (ricordate che il tutorial è basato su sitema Fedora 8 ) che indica il

socket per la connessione al database.In OPTIONS si possono dare diverse altre

impostazioni ,che non starò certo ad elencare tutte,in questa guida ,ripeto, tante cose

sarò costretto a sorvolarle ,per motivi di ampiezza,in quanto Django è molto esteso,

mi limiterò a quegli aspetti comunemente ritenuti importanti e, personalmente che

ritengo ,in base alla mia esperienza ,di probabile cattiva comprensione ,per tanti motivi.

Mi limiterò ad indicare tra le  voci possibili in OPTIONS autocommit ‘ = True,

che ,per chi non lo sapesse serve ,nel caso di query multiple,ad annullarle tutte nel

caso anche una sola non dovesse andare in porto.

Dicevamo ,il database con alias DEFAULT , è quello principale , che è obbligatorio

dichiarare ,e che quando non viene specificato è quello usato .Ad esempio quando

usiamo il comando syncdb , per sicronizzare il codice scritto con il database ,se

volgiamo usare un database diverso da quello di default dobbiamo specificarlo

attraverso l opziione –database :

[gianluca@samson sito]$ python manage.py syncdb –database=data1

Comunque django ci da la possibilità di usare piu database insieme,perchè potremmo

decidere,avendo piu applicazioni nell ambito di uno stesso progetto,di memorizzare

i modelli di una in un database ,e quelli dell altra in un altro ,anche diversi server ,ad

esempio mysql ed oracle.Nel mio caso invece in una stessa applicazione ,ho deciso di

memorizzare i models nel database di alias ‘data1‘ , nel database di alias ‘ default ‘ ,

tutto il resto di tabelle che servono al funzionamento di django.

Django ci offre comunque diversi modi per usare piu di un solo database ( DEFAULT ),

ad esempio abbiamo la keyword using , essa puo essere usata in diversi modi,ad

esempio nelle query di ORM.Se per caso vogliamo richiamare tutti gli oggetti di tipo

Libro dal database di default basta scrivere:

Libro.objects.all()

,ripeto questa query userà il db di default,se vogliamo sceglierlo noi faremo:

Libro.objects.using(‘data1′).all()

Oppure ancora se vogliamo salvare un oggetto Libro in un database da noi scelto:

Lib = Libro(title=’La bibbia’)

Lib.save(using=’data1′)

Abbiamo un metodo per determinare a priori quale database django andrà ad usare

senza usare la keyword using nelle query ORM.Possiamo usare l’ opzione

DATABASE_ROUTER.Per farlo dobbiamo creare una classe che indica a django

come comportarsi con i vari oggetti.Personalmente ho creato nella directory dell

applicazione ( app_1 )un file di nome dbrouter.py, ma avremmo potuto farlo

anche scrivendo la classe nel file models.py . Nel file scriviamo la classe :

class my_router(object):

def db_for_read(self, model, **hints):

return self.__app_router(model)

def db_for_write(self, model, **hints):

return self.__app_router(model)

def allow_relation(self, obj1, obj2, **hints):

#return obj1._meta.app_label == obj2._meta.app_label

return True

def allow_syncdb(self, db, model):

return self.__app_router(model) == db

def __app_router(self, model):

#

# per tutti i models che appartengono ad app_1

if model._meta.app_label == ‘app_1′:

return ‘data1′

else:

return ‘default’

Questa classe rappresenta il router del database ,cioè colui che spiega a django a

quale database fare riferimento per ogni tipo di occorrenza.

Innanzitutto dobbiamo settare nel file settings.py un ulteriore voce :

DATABASE_ROUTER = [ sito.app_1.dbrouter.my_router ]

Esso rappresenta una tupla dove gli elementi rappresentano il percorso a partire

dal path,della classe router del database.Ho scritto ‘ elementi ‘ si , perchè possono

esserci piu classi a fare da router ,che instradano le connessioni al database.

Spieghiamo adesso la classe my_router :

Il primo metodo :

def db_for_read(self, model, **hints):

return self.__app_router(model)

Esso deve ritornare l alias del database che vogliamo sia usato per le operazioni di

lettura di  determinati models, (cioè oggetti ,classi create in models.py )

Questo avviene grazie al metodo ultimo ,che è il return del metodo sopra, infatti

def __app_router(self, model):

if model._meta.app_label == ‘app_1′:

return ‘data1′

else:

return ‘default’

Qui  model.meta.app_label ritorna  il nome ( label ) della applicazione a cui fanno

riferimento i models-oggetti-classe che andiamo ad incontrare nelle query

ed utility tipo manage.py. Se essa torna app_1 ,come è ovvio ,dato che nel progetto

sito ‘ abbiamo una sola applicazione ( app_1 ), il metodo ritornerà l’ alias  data1.

Mentre  per tutti gli oggetti che non faranno riferimento ad app_1,si leggerà dal

database di alias  ‘ default ‘ . Quindi il primo metodo

db_for_read(self, models, **hints) ritorna True ( data1 ).

Il secondo metodo :

def db_for_write(self, model, **hints):

return self.__app_router(model)

Stessa procedura del primo, solo che si occupa delle operazioni di scrittura.

Il terzo :

def allow_relation(self, obj1, obj2, **hints):

return True

Si occupa di stabilire se tra 2 oggetti  si puo stabilire una relazione.Nel mio caso ,non

ho messo alcun controllo preventivo,ma volendo possiamo porre condizioni per la

relazione.Ad esempio nei tutorial in rete porta un Return così :

return obj1._meta.app_label == obj2._meta.app_label

Significa che se i 2 oggetti di cui scrivere la relazione ,se appartengono alla stessa

applicazione,allora permette di scrivere la relazione nel database

( infatti app_1 == app_1  è True ,in base all algebra do Boole) allora permette di

scrivere la relazione ,altrimenti non lo permette ( False).Questo metodo serve per

quando si usano models con campi di relazione foreign_key (chiavi esterne),

oppure many_to_many (relazione molti a molti ) tra le tabelle .

Fare attenzione affinchè oggetti-models  che contengono campi in relazione,siano

scritti nello stesso database ,infatti solo models che non sono in relazione ,possono

stare in database diversi.

Il quarto metodo :

def allow_syncdb(self, db, model):

return self.__app_router(model) == db

Ritorna Tue se model puo essere sincronizzato al database db.Cioè quando facciamo:

[gianluca@samson sito]$ python manage.py syncdb –database=data1

cioè se volgiamo sincronizzare gli oggetti-models  nel db = data1 ,

self.__app_router(model) ritorna  data1 in caso di classi in models.py,dato che

model._meta.app_label == ‘app_1′ . Quindi il metodo ritorna True ,e la

sicronizzazione scriverà le tabelle dei models e delle relazioni tra essi nel database

alias = ‘ data1 ‘  . Se il db = ‘ default ‘ , e il model non ha attributo

meta.app_label == ‘app_1′ (cioè non è una classe in models.py) significa che

(non avendo altre applicazioni nel progetto ‘ sito ‘ ) si tratta di classi-oggetto-model

generiche al funzionamento di django ,per questo il metodo

my_router __app_router(self, model) ritornerà ‘ default ‘ .Perciò quando  :

[gianluca@samson sito]$ python manage.py syncdb –database=default

Oppure il piu generico (e che ha sempre in considerazione il db ALIAS default) :

[gianluca@samson sito]$ python manage.py syncdb

Tutti gli oggetti-classe in model.py dell applicazione  app_1 , non verranno

sincronizzati ,in quanto return self.__app_router(model) == db torna FALSE,

perchè __app_router(self, model) tornerebbe data1,mentre il db == default

(sia se lo esplicitiamo o meno).Mentre gli oggetti genereci interni a DJANGO come

ad esempio le classi dell amministrazioni ,e tutte quelle a lui funzionali ,verranno

creati nel database con alias  ‘ default ‘.

Un ultima cosa riguardo l argomento **hints esso si riferisce ad un eventuale

opzionale argomento per le funzioni di router sopra.Ad esempio potrebbe

definire eventuali istanze dei modelli-classe ,su cui differenziare la scelta

dei database nel quale sincrinizzarlo.Mentre sopra le funzioni selezionavano la

sync in base al rapporto modello->db,questo parametro differenzia ad un gradino

diverso di scala    .  istanza->classe->db.

Proseguiamo con i settaggi del file settings.py.

Ricordo che spiegherò solo le voci che riterrò importanti ,quelle autodescrittive

le lascerò da parte. Continuiamo a spiegare le opzioni di settings.py ,spiegando

quelle che fanno riferimento alla localizzazione ed internazionalizazzione ,cioè

la formattazione dell output (ora , data ,linguaggio usato).

Passeremo quindi ad un altro capitolo.

parte2

parte4


Leave a Reply

Your email address will not be published.


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>