Configurazione Django semiautomatica

Scritto da Riccardo Attilio Galli
./init.sh percorso/del/nuovo/progetto/django

È semplicissimo!

Otterrai un progetto Django con una struttura professionale (vedi sotto) e con i permessi preimpostati, configurazioni multiple (di base per sviluppo e produzione, puoi aggiungerne quante ne vuoi), cache basata su filesystem, logging, raggruppamento/riduzione di javascript e css, localizzazione, una configurazione di esempio di virtualhost per Apache, file da ignorare da git preconfigurati in modo da iniziare immediatamente a fare commit e un file per fabric in modo da automatizzare i task più ripetitivi. Ovviamente il tutto all'interno di un ambiente virtualenv e senza dimenticare una struttura HTML5 base.

Nessun trucco. Puoi cambiare ogni cosa.

Dovrai configurare alcune cose per soddisfare i tuoi bisogni, ma sappi che otterrai sin da subito un progetto funzionante. Le cose da fare noiose e soggette ad errori sono già state fatte, in modo che tu possa iniziare a sviluppare il prima possibile (dovrai comunque rileggere le configurazioni per cambiare cose quali la timezone ma si tratta di pochi minuti, e vorrai comunque modificare queste cose).

Perché?

Dopo l'ennesima volta in cui ho cominciato un progetto Django, creato una struttura adatta a sviluppo/stage/produzione, configurato le cose principali ed essere sommerso da piccoli errori (logs introvabili, permessi imperfetti, inconsistenze della cache) ho deciso di automatizzare l'inizio del progetto.

Un progetto deve essere semplice ed iniziare bene, avere una struttura razionale e una piccola quantità di cose che devono funzionare sin dall'inizio (come la cache o il raggruppamento/riduzione di javascript e css). Non deve essere tutto configurato al meglio sin da subito (per esempio la cache non deve essere immediatamente memcache) ma deve funzionare ed essere aggiornabile in futuro (come una iniziale cache su filesystem piuttosto che memcache).

Dove posso scaricarlo?

I sorgenti più aggiornati si trovano al repository git ufficiale

Come si usa?

./init.sh percorso/del/nuovo/progetto/django

Se la directory non esiste verrà creata. Lo script proverà ad assegnare il gruppo e i permessi corretti. Se non riuscisse ti dirà cosa fare.

Perché la documentazione è così lunga?

Sebbene semplici ci sono molte cose fatte dietro le quinte. Per sapere cosa è stato fatto puoi leggere il codice (non è così tanto, davvero) oppure leggere questo manuale per sapere esattamente cosa è stato configurato.

Che cosa fa lo script?

  • crea la directory del progetto (chmod 2750) se non esiste ed entra
  • configura umask 0027 (others non possono legere i file e il gruppo di default può solo leggere)
  • scarica virtualenv e lo installa assieme a pip nella directory .env
  • attiva l'ambiente virtuale
  • installa le librerie presenti in base_project/requirements/default_install.txt
  • copia il contenuto di base_project nella directory
  • dà i permessi di scrittura al gruppo in alcune directory (e.g. /var/tmp e /var/log)
  • crea alcuni file di log vuoti per assicurarsi che appartengano all'utente
  • colleziona stringhe di localizzazione già presenti e file statici, comprime ciò che può (per dimostrare che funziona)
  • esce da virtualenv, ripristina l'umask originale ed entra nella directory di partenza

Come è strutturato il progetto?

  • apps/ # qui vanno le tue applicazioni
  • configs/ # configurazioni dei server. Ce ne sono alcune di base
    • develop/
    • production/
  • fabfile/ # fabric files
  • locale/ # directory per traduzioni generiche per tutto il progetto
    • en/
      • LC_MESSAGES/
  • requirements/ # ogni volta che usi pip freeze per salvare le tue dipendenze, salva qui il risultato
  • static/ # file statici a livello di progetto (e.g. favicon o css globale)
    • admin/
    • public/
  • templates/ # template a livello di progetto
    • layout/ # template che danno struttura ad una pagina
    • views/ # viste generiche non legate ad una applicazione
  • var/ # file variabili
    • log/ # ovviamente i log
    • media/ # upload di utenti
    • static/ # tutti i file statici collezionati del progetto
    • tmp/ # directory per file temporanei

Ho lanciato lo script. E ora ?

Inizia col versioning del progetto.

Se usi git si è già provveduto ad ignorare tutti i file che non vanno versionati.

Devi solo inizializzare il tuo progetto

git init .
git add .
git commit -m "Prima commit"

Se usi un altro vcs come mercurial o bazaar dovrai fare alcune cose.

Per piacere ignora il contenuto di

  • .env/
  • var/media/
  • var/static/
  • var/log/
  • var/tmp/
  • local_settings.py # anywhere
  • fabfile/*_settings.py
  • any *.pyc *.pyo

Controlla che funzioni

Qui e dopo, ricorda sempre che devi accedere all'ambiente virtualenv

source .env/bin/activate

Avvia il server con la configurazione di sviluppo

python manage.py runserver

Controlla su http://localhost:8000/ che ci sia una pagina di benvenuto. Leggi il sorgente HTML, noterai più file CSS caricati (normalize.css e main.css).

Prova ad accedere ad una url inesistente per vedere la pagina 404 di django.

Avvia il server con la configurazione di produzione

TARGET="production" python manage.py runserver

Vedrai la stessa pagina di prima ma quando la ricarichi non verrà più aggiornata l'ora (cache abilitata). Controlla i sorgenti della pagina, ci sarà adesso un solo file compresso per css ed uno per javascript (quindi css e javascript vengono aggregati e compressi). Se provi ad accedere ad una url casuale ti verrà presentata una pagina 404 ad hoc.

Se qualcosa non funzionasse per piacere apri un ticket.

Comprendere la struttura delle configurazioni

Le configurazioni sono salvate come

configs/<confname>/settings.py

Per creare una configurazione per il tuo server di stage o preproduzione

configs/stage/settings.py

potrai utilizzarla via

TARGET="stage" python manage.py runserver

come avrai immaginato "develop" è il target di default.

Informazioni confidenziali vanno salvate in un file di nome local_settings.py nella stessa directory dove si trova il file settings.py. I file di nome local_settings.py non vengono versionati.

Troverai un esempio. Dati tipici che finiscono lì sono password di database e chiave di API.

Rilleggi le configurazioni

Leggi pure il contenuto di develop e production settings.py.

Nota: il file settings.py di produzione eredita il contenuto di quello di sviluppo e riscrive o aggiunge regole. Se questo comportamento non ti piace perché potresti abilitare qualcosa in sviluppo e dimenticare di disabilitarla in produzione, dovrai copiare il file settings.py di sviluppo in

configs/production/

e modificare/aggiungere ciò che hai trovato nel file originale in production

Riguardo alle configurazioni, ciò che devi proprio controllare ed eventualmente cambiare sono:

  • TIME_ZONE
  • SITE_ID
  • LANGUAGE_CODE and LANGUAGES

Inoltre in local_settings.py (puoi copiare e cambiare local_settings.py.example)

  • SECRET_KEY
  • ADMINS
  • DATABASES

Una nota sui database

Non è stato installato alcun database driver perché ci sono troppe opzioni. Di seguito c'è una lista incompleta di alcuni dei più noti database e rispettive librerie

  • PostgreSQL - pip install psycopg2
  • MySQL - pip install MySQL-python
  • SQLite - pip install pysqlite

Configurare Apache

Se vuoi usare Apache come webserver per il tuo progetto Django puoi iniziare con la configurazione presente in webserver_example_confs/apache.conf. Ho utilizzato mod_macro perché è più semplice poi amministrare la configurazione (devi solo cambiare l'ultima riga!)

Use VHost <hostname> /percorso/del/nuovo/progetto/django <confname>

Se non puoi installare mod_macro dovrai rimuovere la riga in cui viene caricato e i tag macro che racchiudano l'intera configurazione. Ovviamente dovrai anche sostituire ogni variabile con il valore corrispondente (ed inizierai a chiederti se non c'è un modo per installare quel comodissimo mod_macro).

Come prima, la configurazione è fatta per andare subito, modificati quei tre parametri. Se non funzionasse, ticket.

Log

I log sono salvati in var/logs. Ci sono tre log inizialmente

  • apache-access.log - tutte le richieste al server
  • apache-error.log - ogni errore che non ha permesso di arrivare a Django
  • django.log - ogni errore occorso durante l'uso di Django (con la configurazione di produzione) o di ogni messaggio di livello pari o superiore a DEBUG (con la configurazione di sviluppo). Il nome del logger è 'django'

Esempio di come scrivere su un log in Django

from django.utils.log import getLogger
logger = getLogger('django')
logger.debug('debug log test')

Ricorda di usare un nome di logger specifico per applicazione e di configurarlo sotto LOGGING.

I log non sono ruotati automaticamente, dovrai aggiungere un cron job per quello.

Template

Per semplificare il design del sito ho aggiunto due directory ad una template dir globale.

  • templates/layout
  • templates/views

Layouts contiene i templates che danno una struttura alla pagina mentre in views teniamo solo contenuti parziali. Poiché questa directory template è globale solo alcune particolari viste dovrebbero andare in templates/views (come una about page) mentre viste legate ad applicazioni dovrebbero stare nella directory template dell'applicazione.

I layout di default sono

  • base.html
  • content_only.html
  • header_footer.html

Tutti loro hanno in comune un blocco chiamato "content", in modo che quando scrivi una vista sia sufficiente estendere un layout e sovrascrivere il blocco "content". Per cambiare il layout sarà quindi sufficiente cambiare il file da cui estende (scegliendone un altro da templates/layout/).

e.g.

{% extends "layout/base.html" %}

{% block content%}Hello world{% endblock %}
{% extends "layout/header_footer.html" %}

{% block content%}Hello world{% endblock %}

base.html contiene la più semplice pagina. Solo i tag <html><head> e <body>, con dei django template blocks per gestire css e javascript (con compressione preimpostata). Non dovrebbe essere stilizzata in modo particolare.

content_only.html ha semplicemente un div #main-content con all'interno il block "content". Aggiungi un po' di stile a main.css per servirci pagine come quella di 'about'.

header_footer.html questo layout aggiunge <header> e <footer> intorno a quello stesso container presente nel layout "content_only".

Questi sono i layout più semplici ed utili che mi sono venuti in mente, aggiungerne uno (per esempio un layout a due colonne) è semplicissimo. Crea il file in templates/layout/ ed assicurati che abbia un blocco chiamato "content".

Fabric e amministrazione

Per amministrare il sito puoi usare Fabric. C'è una configurazione non banale in

fabfile/__init__.py

per connettersi ad un host remoto e lanciare i più comuni task (collezionare file statici, comprimere css/js, svuotare la cache e altro). Ho messo in piedi un sistema che permetta di avere file di configurazione separati, come

<confname>_settings.py

Devono stare nella directory fabfile/. Questo permette di evitare il versionamento di informazioni confidenziali (se usi git questi file vengono già ignorati).

Nota che <confname> deve essere il nome di una delle configurazioni presenti in 'configs/'.

Sistemi operativi supportati

Funziona correntemente sotto GNU/Linux

blog comments powered by Disqus