Best practice per la struttura delle directory di lavoro del progetto Django


174

So che in realtà non esiste un unico modo giusto. Tuttavia ho scoperto che è difficile creare una struttura di directory che funzioni bene e rimanga pulita per ogni sviluppatore e amministratore. Esiste una struttura standard nella maggior parte dei progetti su github. Ma non mostra un modo per organizzare altri file e tutti i progetti su PC.

Qual è il modo più conveniente per organizzare tutte queste directory sulla macchina di sviluppo? Come li nominate e come connettete e distribuite questo al server?

  • progetti (tutti i progetti su cui stai lavorando)
  • file di origine (l'applicazione stessa)
  • copia funzionante del repository (io uso git)
  • ambiente virtuale (preferisco posizionarlo vicino al progetto)
  • radice statica (per file statici compilati)
  • media root (per file multimediali caricati)
  • LEGGIMI
  • LICENZA
  • documenti
  • schizzi
  • esempi (un progetto di esempio che utilizza l'applicazione fornita da questo progetto)
  • database (nel caso in cui venga utilizzato sqlite)
  • qualsiasi altra cosa di cui di solito hai bisogno per lavorare con successo sul progetto

I problemi che voglio risolvere:

  • Buoni nomi di directory in modo che il loro scopo sia chiaro.
  • Conservando tutti i file di progetto (incluso virtualenv) in un unico posto, in modo da poter facilmente copiare, spostare, archiviare, rimuovere l'intero progetto o stimare l'utilizzo dello spazio su disco.
  • Creazione di più copie di alcuni set di file selezionati come l'intera applicazione, repository o virtualenv, mantenendo una singola copia di altri file che non voglio clonare.
  • Distribuire il giusto set di file sul server semplicemente risincronizzando una directory selezionata.

Risposte:


257

Ci sono due tipi di "progetti" di Django che ho nella mia ~/projects/directory, entrambi hanno una struttura leggermente diversa .:

  • Siti Web autonomi
  • Applicazioni collegabili

Sito Web autonomo

Principalmente progetti privati, ma non devono esserlo. Di solito si presenta così:

~/projects/project_name/

docs/               # documentation
scripts/
  manage.py         # installed to PATH via setup.py
project_name/       # project dir (the one which django-admin.py creates)
  apps/             # project-specific applications
    accounts/       # most frequent app, with custom user model
    __init__.py
    ...
  settings/         # settings for different environments, see below
    __init__.py
    production.py
    development.py
    ...

  __init__.py       # contains project version
  urls.py
  wsgi.py
static/             # site-specific static files
templates/          # site-specific templates
tests/              # site-specific tests (mostly in-browser ones)
tmp/                # excluded from git
setup.py
requirements.txt
requirements_dev.txt
pytest.ini
...

impostazioni

Le impostazioni principali sono quelle di produzione. Altri file (ad es. staging.py, development.py) Importano semplicemente tutto production.pye sovrascrivono solo le variabili necessarie.

Per ogni ambiente, esistono file di impostazioni separati, ad es. produzione, sviluppo. Ho alcuni progetti che ho anche testato (per test runner), messa in scena (come controllo prima della distribuzione finale) e heroku (per la distribuzione su heroku).

Requisiti

Preferisco specificare direttamente i requisiti in setup.py. Solo quelli richiesti per l'ambiente di sviluppo / test in cui mi trovo requirements_dev.txt.

Alcuni servizi (ad es. Heroku) devono essere presenti requirements.txtnella directory principale.

setup.py

Utile quando si distribuisce il progetto usando setuptools. Si aggiunge manage.pya PATH, quindi posso eseguire manage.pydirettamente (ovunque).

App specifiche del progetto

Ho usato per mettere queste app nella project_name/apps/directory e importarle usando le relative importazioni.

File template / static / locale / test

Ho inserito questi modelli e file statici in modelli globali / directory statiche, non all'interno di ogni app. Questi file sono generalmente modificati da persone che non si preoccupano affatto della struttura del codice di progetto o di Python. Se sei uno sviluppatore full-stack che lavora da solo o in un piccolo team, puoi creare modelli per-app / directory statica. È davvero solo una questione di gusti.

Lo stesso vale per le impostazioni locali, sebbene a volte sia conveniente creare una directory delle impostazioni locali separata.

Di solito è meglio posizionare i test all'interno di ogni app, ma di solito ci sono molti test di integrazione / funzionali che testano più app che lavorano insieme, quindi la directory dei test globali ha senso.

Directory Tmp

Esiste una directory temporanea nella radice del progetto, esclusa da VCS. Viene utilizzato per archiviare file multimediali / statici e database sqlite durante lo sviluppo. Tutto in tmp può essere eliminato in qualsiasi momento senza problemi.

vIRTUALENV

Preferisco virtualenvwrappere posiziono tutti i venv nella ~/.venvsdirectory, ma potresti metterlo all'interno tmp/per tenerlo insieme.

Modello di progetto

Ho creato un modello di progetto per questa configurazione, django-start-template

Distribuzione

La distribuzione di questo progetto è la seguente:

source $VENV/bin/activate
export DJANGO_SETTINGS_MODULE=project_name.settings.production
git pull
pip install -r requirements.txt

# Update database, static files, locales
manage.py syncdb  --noinput
manage.py migrate
manage.py collectstatic --noinput
manage.py makemessages -a
manage.py compilemessages

# restart wsgi
touch project_name/wsgi.py

È possibile utilizzare rsyncinvece di git, ma è comunque necessario eseguire batch di comandi per aggiornare l'ambiente.

Di recente, ho realizzato [django-deploy][2]un'app che mi consente di eseguire un singolo comando di gestione per aggiornare l'ambiente, ma l'ho usata solo per un progetto e sto ancora sperimentando.

Schizzi e bozze

Bozza di modelli che inserisco nella templates/directory globale . Immagino che uno possa creare una cartella sketches/nella radice del progetto, ma non l'ho ancora usato.

Applicazione collegabile

Queste app sono generalmente pronte per essere pubblicate come open-source. Ho preso un esempio di seguito da Django-forme

~/projects/django-app/

docs/
app/
tests/
example_project/
LICENCE
MANIFEST.in
README.md
setup.py
pytest.ini
tox.ini
.travis.yml
...

Il nome delle directory è chiaro (spero). Ho messo i file di test fuori dalla directory dell'app, ma non importa. È importante fornire READMEe setup.py, quindi il pacchetto può essere facilmente installato pip.


Grazie! Mi piace la tua struttura. Mi ha dato idee utili. Aspetti positivi sull'utilizzo di setup.py per i requisiti e l'installazione di manage.py in PATH. Potresti per favore mostrare come fai l'ultima cosa? Anche un buon punto sulla dir 'tmp'. Preferirei chiamarlo "local", quindi potrei avere "env", "tmp" e qualsiasi cosa anche all'interno. Questo risolve il problema di avere troppi affari con gitignore. Un nuovo problema è che questo nome è troppo vicino a "locale". Forse ha senso spostare 'locale' nell'app principale 'project_name', non ne sono sicuro. Non voglio cambiare struttura a causa di un brutto nome. Eventuali suggerimenti?
raacer,

Quando si utilizza setup.py, aggiungere l' scriptsargomento della parola chiave: github.com/elvard/django-start-template/blob/master/project/… Mi piace tmpperché suggerisce "qualcosa di temporaneo" che può essere rimosso in qualsiasi momento. Toplevel localedir non è necessario, puoi posizionarlo ovunque. Mi piace solo che sia coerente con le directory statiche / template.
Tomáš Ehrlich,

Il mio requisito per la capacità di fare diverse copie dei file di origine senza copiare altri file non è risolto direttamente. Ma l'obiettivo può ancora essere archiviato usando git checkouto escludendo solo una dir 'tmp' durante la clonazione della directory del progetto. Quindi sembra che la tua struttura soddisfi tutti i requisiti, ed è abbastanza chiara da usare su base regolare senza alcun dubbio. Accetto la tua risposta. Grazie.
raacer,

Grazie. Non capisco ancora cosa intendi per "capacità di fare diverse copie dei file sorgente senza copiare altri file". Ottimizzato il comando rsync farebbe, ma probabilmente non è quello che vuoi dire ...
Tomáš Ehrlich

Di solito creo dir srcall'interno della radice del progetto. Questa è la copia di lavoro dei file sorgente e della radice del repository git. Posso fare diverse copie di questo elenco - src, src.bak, src_tmpe così via. Altri dirs non pronti contro termine come env, tmp, media, backuprisiedono sullo stesso livello. Quindi posso cp -r src src.bakfarlo in qualsiasi momento e voglio fare qualche esperimento con git o confrontare le versioni con uno strumento esterno. Mentre hai dei file locali all'interno del tuo repository, ho un repository all'interno della mia directory dei file locali (viceversa). Il nome migliore della mia srcdir è repo.
raacer

19

La mia risposta è ispirata alla mia esperienza lavorativa, e soprattutto nel libro Two Scoops of Django che consiglio vivamente, e dove puoi trovare una spiegazione più dettagliata di tutto. Risponderò solo ad alcuni punti e qualsiasi miglioramento o correzione sarà accolto con favore. Ma ci possono essere anche modi più corretti per raggiungere lo stesso scopo.

Progetti
Ho una cartella principale nella mia directory personale in cui mantengo tutti i progetti su cui sto lavorando.

File sorgente
Uso personalmente la radice del progetto django come radice del repository dei miei progetti. Ma nel libro si raccomanda di separare entrambe le cose. Penso che questo sia un approccio migliore, quindi spero di iniziare a fare il cambiamento progressivamente sui miei progetti.

project_repository_folder/
    .gitignore
    Makefile
    LICENSE.rst
    docs/
    README.rst
    requirements.txt
    project_folder/
        manage.py
        media/
        app-1/
        app-2/
        ...
        app-n/
        static/
        templates/
        project/
            __init__.py
            settings/
                __init__.py
                base.py
                dev.py
                local.py
                test.py
                production.py
            ulrs.py
            wsgi.py

Repository
Git o Mercurial sembrano essere i sistemi di controllo versione più popolari tra gli sviluppatori Django. E i servizi di hosting più popolari per i backup GitHub e Bitbucket .

Ambiente
virtuale Uso virtualenv e virtualenvwrapper. Dopo aver installato il secondo, è necessario impostare la directory di lavoro. Il mio è nella mia directory / home / envs , come è raccomandato nella guida all'installazione di virtualenvwrapper. Ma non credo che la cosa più importante sia dove si trova. La cosa più importante quando si lavora con ambienti virtuali è mantenere aggiornato il file requisito.txt.

pip freeze -l > requirements.txt 


Cartella Progetto radice statica


Cartella del progetto radice multimediale

README
Radice repository

LICENZA
Radice repository

Documenti
radice del repository. Questi pacchetti python possono aiutarti a semplificare la gestione della documentazione:

Sketches

Esempi

Banca dati


Grazie per aver condiviso la tua esperienza. Ci sono molte directory 'project *' nella tua struttura. Probabilmente non usi questi nomi nella vita reale, giusto? Diciamo che abbiamo un progetto "todo". Come si chiamano queste dir in questo caso? Il problema che vedo nella tua attuale struttura è mescolare il repository con file non repository (come hai notato sopra). Potrebbe essere fastidioso aggiungere qualche cestino a .gitignore, non è vero? Un'altra cosa dubbia è mantenere l'ambiente diretto così lontano dal progetto stesso. Ha senso? Perché non creare ~ / docs, ~ / statics e così via? Anche a Git piace sedersi vicino ai file sorgente.
raacer

Vorrei nominarli: "todo_project" -> todo -> todo (o forse todoapp). Penso che sia importante essere nella cartella del repository nella radice della gerarchia di directory. Ma è solo la mia opinione. Per quanto riguarda la directory di ambiente, quando è necessario configurare l'ambiente di produzione, è sufficiente scrivere: pip install -U -r Requisiti.txt. Ma, come ho detto, non esiste una soluzione per tutto.
cor

Quindi il percorso dell'app principale è "progetti / todo_project / todo / todo". La parola "progetti" si è ripetuta due volte e la parola "todo" si è ripetuta tre volte. Sembra "progetti / progetto / mio_programma / progetto_dir / progetto / progetto". I nomi non sono molto chiari. Questo è uno dei maggiori problemi che sto cercando di risolvere nella mia struttura di directory. Voglio nominare le directory per facilitare la comprensione della gerarchia. Che dire del repository root, potresti spiegare perché è importante? Potresti anche spiegare cosa c'è di buono nel mantenere envs al di fuori della direzione del progetto principale?
raacer

13

Non mi piace creare una nuova settings/directory. Aggiungo semplicemente i file con nome settings_dev.pye settings_production.pyquindi non devo modificare il file BASE_DIR. L'approccio seguente aumenta la struttura predefinita invece di cambiarla.

mysite/                   # Project
    conf/
        locale/
            en_US/
            fr_FR/
            it_IT/
    mysite/
        __init__.py
        settings.py
        settings_dev.py
        settings_production.py
        urls.py
        wsgi.py
    static/
        admin/
            css/           # Custom back end styles
        css/               # Project front end styles
        fonts/
        images/
        js/
        sass/
    staticfiles/
    templates/             # Project templates
        includes/
            footer.html
            header.html
        index.html
    myapp/                 # Application
        core/
        migrations/
            __init__.py
        templates/         # Application templates
            myapp/
                index.html
        static/
            myapp/
                js/  
                css/
                images/
        __init__.py
        admin.py
        apps.py
        forms.py
        models.py
        models_foo.py
        models_bar.py
        views.py
    templatetags/          # Application with custom context processors and template tags
        __init__.py
        context_processors.py
        templatetags/
            __init__.py
            templatetag_extras.py
    gulpfile.js
    manage.py
    requirements.txt

Io penso questo:

    settings.py
    settings_dev.py
    settings_production.py

è meglio di questo:

    settings/__init__.py
    settings/base.py
    settings/dev.py
    settings/production.py

Questo concetto si applica anche ad altri file.


Di solito inserisco node_modules/e bower_components/nella directory del progetto nella static/cartella predefinita .

A volte una vendor/directory per i sottomoduli Git, ma di solito li inserisco nella static/cartella.


4

Ecco cosa seguo sul mio sistema.

  1. Tutti i progetti : esiste una directory dei progetti nella mia cartella home, ad es ~/projects. Tutti i progetti riposano al suo interno.

  2. Progetto individuale : seguo un modello di struttura standardizzato utilizzato da molti sviluppatori chiamato django-skel per singoli progetti. Praticamente si prende cura di tutti i tuoi file statici e file multimediali e tutti.

  3. Ambiente virtuale : ho una cartella virtualenvs nella mia casa per archiviare tutti gli ambienti virtuali nel sistema, ad es ~/virtualenvs. Questo mi dà la flessibilità di sapere che cosa ho tutti gli ambienti virtuali e che posso sembrare facile da usare

Le 3 precedenti sono le principali partizioni del mio ambiente di lavoro.

Tutte le altre parti che hai citato dipendono in gran parte dal progetto alla base del progetto (cioè potresti usare database diversi per progetti diversi). Quindi dovrebbero risiedere nei loro singoli progetti.


Grazie. Potrebbe essere fastidioso aggiungere qualsiasi cestino a .gitignore quando si mescolano repository con file non repository. Non è vero? Alcuni dei miei progetti hanno fino a dieci e più file e directory, quindi questo rappresenta un vero problema per me. Un'altra cosa dubbia è mantenere l'ambiente diretto così lontano dal progetto stesso. Qual è la flessibilità in tale soluzione? Perché non creare ~ / docs, ~ / statics e così via? Anche a Git piace sedersi vicino ai file sorgente. Ho pensato che la flessibilità fosse quando posso semplicemente copiare / spostare / archiviare / rimuovere l'intera directory del progetto incluso virtualenv e posso facilmente gestire più envs all'interno di un progetto
raacer

4

Secondo lo scheletro del progetto Django, la struttura di directory corretta che potrebbe essere seguita è:

[projectname]/                  <- project root
├── [projectname]/              <- Django root
   ├── __init__.py
   ├── settings/
      ├── common.py
      ├── development.py
      ├── i18n.py
      ├── __init__.py
      └── production.py
   ├── urls.py
   └── wsgi.py
├── apps/
   └── __init__.py
├── configs/
   ├── apache2_vhost.sample
   └── README
├── doc/
   ├── Makefile
   └── source/
       └── *snap*
├── manage.py
├── README.rst
├── run/
   ├── media/
      └── README
   ├── README
   └── static/
       └── README
├── static/
   └── README
└── templates/
    ├── base.html
    ├── core
       └── login.html
    └── README

Consultare https://django-project-skeleton.readthedocs.io/en/latest/structure.html per la struttura delle directory più recente.


7
Odio l'approccio [nome progetto] / [nome progetto]!)
raacer,

1
django-project-skeleton non è "la documentazione di Django". Sarebbe più accurato dire "Secondo il django-project-skeleton, ...".
David Winiecki,

0

È possibile utilizzare il repository https://github.com/Mischback/django-project-skeleton .

Esegui sotto il comando:

$ django-admin startproject --template=https://github.com/Mischback/django-project-skeleton/archive/development.zip [projectname]

La struttura è qualcosa del genere:

[projectname]/                  <- project root
├── [projectname]/              <- Django root
   ├── __init__.py
   ├── settings/
      ├── common.py
      ├── development.py
      ├── i18n.py
      ├── __init__.py
      └── production.py
   ├── urls.py
   └── wsgi.py
├── apps/
   └── __init__.py
├── configs/
   ├── apache2_vhost.sample
   └── README
├── doc/
   ├── Makefile
   └── source/
       └── *snap*
├── manage.py
├── README.rst
├── run/
   ├── media/
      └── README
   ├── README
   └── static/
       └── README
├── static/
   └── README
└── templates/
    ├── base.html
    ├── core
       └── login.html
    └── README
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.