Python - Django - 1 - Settings, Url, Modello

django python

Nell'articolo introduttivo della mini-serie su Django è stata presentata una panoramica sulle componenti principali del framework. Abbiamo visto che Django si basa sul paradigma MTV, Model-Template-View, per gestire la comunicazione tra il front-end delle applicazioni web ed il modello sottostante. In questo articolo, dopo una breve introduzione ai principali file di configurazione delle applicazioni in Django, analizzeremo la parte di creazione e gestione del Modello, utilizzando come esempio una semplice applicazione di e-commerce.
Cominciamo quindi impostando l'ambiente di sviluppo come spiegato nell'articolo precedente, ed eseguiamo il seguente comando per creare la nostra applicazione di ecommerce:
django-admin.py startproject web_application .
cd web_application/
python manage.py startapp ecommerce


Configurare l'applicazione

I file di configurazione principali si trovano all'interno della root della cartella del progetto. Nel caso in esame, dobbiamo spostarci nella cartella web_application. Analizziamo adesso i moduli python settings.py e urls.py. Il file wsgi.py sarà esaminato nell'ultima parte della mini-serie di articoli.

File settings.py

Il file settings.py contiene tutte le configurazioni dell'applicazione. E' gestito come un modulo python, in cui ogni variabile definisce una configurazione. Alcune variabili sono automaticamente generate tramite il comando startproject, mentre altre possono essere inserite facendo riferimento alla documentazione ufficiale. Vediamo adesso alcune delle variabili preimpostate da Django:

  • SECRET_KEY: stringa random generata automaticamente dal comando startproject; è la base a partire dalla quale sono crittografate le comunicazioni all'interno dell'applicazione; è altamente sconsigliato condividere il valore della SECRET_KEY di produzione al di fuori dell'applicazione; si consiglia perciò di salvare il contenuto della chiave segreta in un file esterno all'applicazione, differente da settings.py.
  • DEBUG: valore booleano per abilitare le funzionalità di debug; molto utile in fase di sviluppo, è tuttavia sconsigliato lasciare il valore a True in produzione perché potrebbe rivelare informazioni sensibili sull'applicazione.
  • ALLOWED_HOSTS: lista di stringhe che identificano gli host e i domini permessi per l'applicazione.
  • INSTALLED_APPS: lista di stringhe delle applicazioni installate; ogni volta che eseguite il comando startapp dovete ricordarvi di aggiungere alla lista il nome della app che avete creato affinché sia raggiungibile dal sito.
  • MIDDLEWARE: lista di stringhe con i moduli dello strato Middleware utilizzati dall'applicazione; lo strato Middleware entra in gioco quando è inviata una richiesta all'applicazione, prima che questa sia indirizzata verso una view.
  • ROOT_URLCONF: stringa di testo che definisce il path per il file urls.py dell'applicazione.
  • TEMPLATES: lista di dizionari delle configurazioni dei template dell'applicazione.
  • DATABASES: lista di dizionari per la configurazione dei database ai quali si deve connettere l'applicazione; negli esempi presentati utilizzeremo SQLite; in caso di DBMS più complessi, dove è necessario specificare USERNAME e PASSWORD per la connessione, sono consigliati gli stessi accorgimenti spiegati per la variabile SECRET_KEY.
  • STATIC_URL: stringa che definisce il path per la cartella dei file di tipo statico: css, immagini, funzioni javascript, ecc...
  • MEDIA_URL: stringa che definisce il path per la cartella dei media caricati.


File urls.py

Ogni volta che un utente fa una richiesta per accedere ad una pagina web della vostra applicazione Django, il framework controlla nel file urls.py se esiste una corrispondenza tra l'indirizzo richiesto e le viste definite nella applicazione.
Django è stato pensato in modo che gli indirizzi delle web application siano il più puliti e concisi possibile. Per ottenere tale chiarezza, sono utilizzati dei file di configurazione chiamati urls.py.
Un file urls.py contiene una lista di tuple chiamata urlpatterns. Il nome è piuttosto esplicativo visto che ogni tupla è formata da:

  • una espressione regolare utilizzata per trovare la corrispondenza con l'indirizzo web richiesto dall'utente;
  • il riferimento alla vista che gestisce la chiamata; tale riferimento può essere passato o tramite il metodo as_view() o con la funzione include
  • altri possibili parametri, tra cui il nome da attribuire all'indirizzo.

Il codice all'interno di /web_applications/urls.py si presenta così:

Dal modulo django.conf.urls sono importati i riferimenti a url, un oggeto che prende in ingresso la tupla di cui sopra, e include, un metodo che prende in ingresso il path verso un altro file di configurazione del tipo urls.py. Nell'esempio mostrato, ogni volta che l'indirizzo inizia con ecommerce/, l'applicazione cerca il matching all'interno del file urls.py dell'applicazione ecommerce. In questo modo è sfruttata la modularità del framework Django.
Del modulo admin parleremo in un prossimo tutorial


Model

Adesso che abbiamo un'idea dei principali file di configurazione di Django, veniamo alla creazione del modello per la nostra applicazione di e-commerce.
Per il momento andremo a creare una semplice ontologia con due entità: prodotto e casa produttrice. Ogni prodotto ha obbligatoriamente una casa produttrice, ed ovviamente una cosa produttrice ha 0 o più prodotti.

Utilizzeremo come chiavi primarie degli id numerici progressivi, ma aggiungeremo anche i vincoli di obbligatorietà per i campi più importanti, e di unicità per il campo nome del prodotto della casa produttrice.

Definiamo le classi Casa e Prodotto all'interno del file ecommerce/models.py. Entrambe le classi derivano dalla classe Model di models. In questo modo, Casa e Prodotto ereditano tutti i metodi e gli attributi per gestire il salvataggio ed il recupero delle istanze dalle tabelle del database.

Attributi

Gli attributi delle classi che devono rappresentare una colonna nelle tabelle del database sono definiti utilizzando le classi Field di models. Nell'esempio mostrato abbiamo:

  • CharField: corrisponde ad un attributo SQL di tipo varchar; è obbligatorio definirne la lunghezza massima.
  • TextField: corrisponde ad un attributo SQL di tipo text; a differenza di CharField, per questa tipologia di campo non deve essere specificata una lunghezza massima; è utile quindi per salvare lunghe descrizioni degli oggetti.
  • EmailField: campo di testo con dei vincoli di integrità definiti per fare in modo che il contenuto sia della forma di un indirizzo di posta elettronica.
  • DecimalField: campo numerico, corrispondente ad un attributo SQL di tipo decimal; ha due campi obbligatori, max_digits e decimal_places.
  • BooleanField: attributo boolean.
  • DateField: corrisponde ad un attributo SQL di tipo date; salva un oggetto Python del tipo datetime.date.
  • FileField: classe Field per il caricamento e salvataggio dei file; è necessario valorizzare i campi MEDIA_ROOT e MEDIA_URL nel file settings.py per permettere il salvataggio dei file caricati.
  • ForeignKey: oggetto usato per definire una relazione uno-a-molti tra due entità; nell'esempio mostrato, ogni prodotto è fabbricato da una casa produttrice; per questo motivo è stato aggiunto il riferimento casa all'interno del modello Prodotto.

Oltre alla relazione uno-a-molti, Django consente l'utilizzo di relazioni uno-a-uno e molti-a-molti grazie alle classi OneToOneField e ManyToManyField.
Django mette a disposizione molte altre classi di tipo Field e permette estendere tali classi per creare oggetti Field ad hoc, come questo progetto per la gestione dei campi criptati.

Parametri

Passiamo in rassegna i differenti parametri utilizzati nella definizione dei campi:

  • null: se impostato a False corrisponde al vincolo NOT NULL di SQL; se impostato a True rende possibile valorizzare l'attributo con valore null.
  • blank: se impostato a False fa in modo che il campo sia considerato obbligatorio e che debba essere obbligatoriamente valorizzato.
  • unique: se impostato a True impone che tutti i valori del campo siano unici, senza ripetizioni.
  • max_length: imposta la lunghezza massima del campo.
  • max_digits: parametro dei campi Decimal, definisce la lunghezza massima del numero salvato, considerando sia parte intera che decimale.
  • decimal_places: parametro dei campi Decimal, definisce il numero di cifre decimale da salvare.
  • on_delete: parametro dei campi per le relazioni tra entità, definisce il comportamento da tenere in caso di cancellazione di una istanza; nell'esempio utilizzato, con l'opzione models.CASCADE, si fa in modo che se una istanza di una casa produttrice è eliminata dalla tabella, tutti i prodotti collegati saranno eliminati di conseguenza.

Meta

In entrambe le classi del modello è definita una sottoclasse Meta. Tale sottoclasse contiene tutte le informazioni che non vogliamo siano salvate come attributi della tabella. Nell'esempio presentato, è stato scelto di indicare il tipo di ordinamento delle tabelle.

Ereditarietà

Django consente di creare gerarchie di entità. Potrebbe essere utile per esempio definire soltanto una volta degli attributi generici che devono essere utilizzati da più entità. Ho aggiunto al codice precedentemente mostrato una classe GenericObject all'interno della quale sono definiti due attributi data, created_at e updated_at. I parametri auto_now_add e auto_now fanno sì che in created_at sia salvata la data in cui l'oggetto è stato creato, mentre in updated_at sia salvata la data dell'ultima modifica all'istanza.
Siccome non vogliamo che sia creata una tabella per GenericObject aggiungiamo alla sottoclasse Meta l'attributo abstract, inizializzato a true.

Popolamento con shell

In un prossimo tutorial vedremo come utilizzare le funzioni di amministrazione per le vostre applicazioni Django. In attesa di ciò, armiamoci di santa pazienza, e popoliamo il nostro database utilizzando la shell di Django.
Sebbene, come vedremo in seguito, l'uso delle funzioni admin sia molto più comodo per inserire nuove istanze, utilizzare la shell vi permetterà di applicare metodi Python definiti nell'applicazione direttamente sulle istanze ottenute. Ciò potrebbe salvarvi la vita se in futuro doveste debuggare il codice online.

Prima di aprire il terminale, ricordiamoci di eseguire i comandi makemigrations e migrate per configurare il database secondo le impostazioni definite dal modello. Spostiamoci col terminale alla base del nostro progetto e digitiamo:
python ./manage.py makemigrations
python ./manage.py migrate

Adesso digitiamo il seguente comando per aprire la shell i Django.
python ./manage.py shell

Dentro la shell, aggiungiamo al nostro database alcune istanze con le istruzioni python mostrate:

Il primo comando importa semplicemente le classi Prodotto e Casa. A questo punto è possibile utilizzare tutti i metodi che si interfacciano col database definiti in objects della classe Model. Con il metodo create inseriamo le nuove istanze nelle tabelle. Si noti che ogni volta che inseriamo un nuovo oggetto Prodotto, dobbiamo attribuirgli un riferimento alla sua casa produttrice. Per questo motivo, utilizziamo il metodo filter per ricercare nella tabella le case produttrici con quello specifico nome. Il metodo ci restituisce un elenco di risultati all'interno di una collezione QuerySet. In questo caso, poiché siamo sicuri che esista una sola casa produttrice col nome cercato, prendiamo l'oggetto di indice 0.

Ipotizziamo infine di voler abbassare il prezzo di un prodotto.

Il metodo save esegue una update dell'oggetto p. Se controllate il valore dell'attributo updated_at vedrete che sarà cambiato rispetto al valore dell'attributo created_at.

Nell'esempio precedente, il metodo save è utilizzato per fare un aggiornamento di un oggetto già esistente, ma può essere utilizzato anche per inserire un nuova instanza:

Infine, è possibile eliminare un oggetto utilizzando il metodo delete:

Nel prossimo articolo della serie su Django vedremo come utilizzare Viste e Template per comunicare col Modello creato e mostrare nelle pagine web le informazioni salvate nel database.

Vi invitiamo come sempre a commentare l'articolo per domande, approfondimento e, soprattutto, correzioni.

Fonti

alessioantonielli
Ingegnere informatico, appassionato di cinema, musica, videogiochi e serie tv. Insomma, le solite cose che vi aspettereste da un ex studente di Ingegneria Informatica, giusto per rafforzare lo stereotipo...
Python - Django - 1 - Settings, Url, Modello ultima modifica: 2017-03-30T21:53:50+00:00 da alessioantonielli


Advertisment ad adsense adlogger