Bonnes pratiques pour la structure du répertoire de travail du projet Django

176

Je sais qu'il n'y a en fait pas de solution unique. Cependant, j'ai trouvé qu'il est difficile de créer une structure de répertoires qui fonctionne bien et reste propre pour chaque développeur et administrateur. Il existe une structure standard dans la plupart des projets sur github. Mais cela ne montre pas un moyen d'organiser d'autres fichiers et tous les projets sur PC.

Quelle est la manière la plus pratique d'organiser tous ces répertoires sur une machine de développement? Comment les nommez-vous et comment connectez-vous et déployez-vous cela sur le serveur?

  • projets (tous les projets sur lesquels vous travaillez)
  • fichiers source (l'application elle-même)
  • copie de travail du référentiel (j'utilise git)
  • environnement virtuel (je préfère placer ceci près du projet)
  • racine statique (pour les fichiers statiques compilés)
  • racine multimédia (pour les fichiers multimédias téléchargés)
  • LISEZ-MOI
  • LICENCE
  • documents
  • croquis
  • exemples (un exemple de projet qui utilise l'application fournie par ce projet)
  • base de données (dans le cas où sqlite est utilisé)
  • tout ce dont vous avez généralement besoin pour réussir votre projet

Les problèmes que je souhaite résoudre:

  • Bons noms de répertoires pour que leur objectif soit clair.
  • Garder tous les fichiers de projet (y compris virtualenv) au même endroit, afin que je puisse facilement copier, déplacer, archiver, supprimer tout le projet ou estimer l'utilisation de l'espace disque.
  • Création de plusieurs copies de certains ensembles de fichiers sélectionnés, tels que l'application entière, le référentiel ou virtualenv, tout en conservant une copie unique d'un autre fichier que je ne souhaite pas cloner.
  • Déployer le bon ensemble de fichiers sur le serveur simplement en resynchronisant un répertoire sélectionné.
raacer
la source

Réponses:

259

Il y a deux types de "projets" Django que j'ai dans mon ~/projects/répertoire, les deux ont une structure un peu différente:

  • Sites Web autonomes
  • Applications enfichables

Site Web autonome

Principalement des projets privés, mais ce n'est pas obligatoire. Cela ressemble généralement à ceci:

~/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
...

Paramètres

Les principaux paramètres sont ceux de production. D'autres fichiers (par exemple staging.py, development.py) importent simplement tout à partir de production.pyet ne remplacent que les variables nécessaires.

Pour chaque environnement, il existe des fichiers de paramètres distincts, par exemple. production, développement. J'ai quelques projets que j'ai également testés (pour le testeur), la mise en scène (comme vérification avant le déploiement final) et les paramètres d'heroku (pour le déploiement sur heroku).

Exigences

Je spécifie plutôt les exigences directement dans setup.py. Seuls ceux requis pour l'environnement de développement / test que j'ai dans requirements_dev.txt.

Certains services (par exemple heroku) nécessitent d'avoir requirements.txtdans le répertoire racine.

setup.py

Utile lors du déploiement d'un projet à l'aide de setuptools. Cela ajoute manage.pyà PATH, donc je peux courir manage.pydirectement (n'importe où).

Applications spécifiques au projet

J'avais l'habitude de mettre ces applications dans un project_name/apps/répertoire et de les importer à l'aide d'importations relatives.

Modèles / static / locale / fichiers de tests

Je mets ces modèles et fichiers statiques dans le répertoire global templates / static, pas dans chaque application. Ces fichiers sont généralement modifiés par des personnes, qui ne se soucient pas du tout de la structure du code du projet ou de Python. Si vous êtes un développeur full-stack travaillant seul ou dans une petite équipe, vous pouvez créer des modèles / répertoire statique par application. C'est vraiment juste une question de goût.

Il en va de même pour les paramètres régionaux, bien qu'il soit parfois pratique de créer un répertoire de paramètres régionaux distinct.

Il est généralement préférable de placer les tests dans chaque application, mais il existe généralement de nombreux tests d'intégration / fonctionnels qui testent plus d'applications fonctionnant ensemble, donc le répertoire de tests global a du sens.

Répertoire Tmp

Il existe un répertoire temporaire à la racine du projet, exclu du VCS. Il est utilisé pour stocker des fichiers multimédias / statiques et une base de données sqlite pendant le développement. Tout dans tmp peut être supprimé à tout moment sans aucun problème.

Virtualenv

Je préfère virtualenvwrapperet place tous les venv dans le ~/.venvsrépertoire, mais vous pouvez le placer à l'intérieur tmp/pour le garder ensemble.

Modèle de projet

J'ai créé un modèle de projet pour cette configuration, django-start-template

Déploiement

Le déploiement de ce projet est le suivant:

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

Vous pouvez utiliser à la rsyncplace de git, mais vous devez quand même exécuter un lot de commandes pour mettre à jour votre environnement.

Récemment, j'ai créé une [django-deploy][2]application, qui me permet d'exécuter une seule commande de gestion pour mettre à jour l'environnement, mais je ne l'ai utilisée que pour un projet et je suis toujours en train de l'expérimenter.

Croquis et brouillons

Brouillon de modèles que je place dans le templates/répertoire global . Je suppose que l'on peut créer un dossier sketches/à la racine du projet, mais je ne l'ai pas encore utilisé.

Application enfichable

Ces applications sont généralement prêtes à être publiées en open source. J'ai pris l'exemple ci - dessous de django-forme

~/projects/django-app/

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

Le nom des répertoires est clair (j'espère). Je place les fichiers de test en dehors du répertoire de l'application, mais cela n'a vraiment pas d'importance. Il est important de fournir READMEet setup.py, donc le package est facilement installé via pip.

Tomáš Ehrlich
la source
Je vous remercie! J'aime ta structure. Cela m'a donné des idées utiles. Bons points sur l'utilisation de setup.py pour les exigences et l'installation de manage.py dans PATH. Pourriez-vous s'il vous plaît montrer comment vous faites la dernière chose? Aussi bon point à propos de 'tmp' dir. Je préfère le nommer «local», puis j'aurai peut-être «env», «tmp» et tout ce qu'il y a à l'intérieur. Cela résout le problème d'avoir trop de transactions avec gitignore. Un nouveau problème est que ce nom est trop proche de «locale». Peut-être qu'il est judicieux de déplacer 'locale' vers l'application principale 'project_name', pas sûr. Je ne veux pas changer de structure à cause d'un mauvais nom. Aucune suggestion?
raacer
Lorsque vous utilisez setup.py, ajoutez un scriptsargument de mot clé: github.com/elvard/django-start-template/blob/master/project / ... J'aime tmpparce qu'il suggère "quelque chose de temporaire" qui peut être supprimé à tout moment. Toplevel localedir n'est pas nécessaire, vous pouvez le placer n'importe où. J'aime juste qu'il soit cohérent avec les répertoires static / templates.
Tomáš Ehrlich
Mon exigence de capacité à faire plusieurs copies de fichiers source sans copier un autre fichier n'est pas résolue directement. Mais l'objectif peut toujours être archivé en utilisant git checkoutou en excluant un seul répertoire 'tmp' lors du clonage du répertoire du projet. Il semble donc que votre structure réponde à toutes les exigences et qu'elle soit suffisamment claire pour être utilisée régulièrement sans aucun doute. J'accepte votre réponse. Je vous remercie.
raacer
Je vous remercie. Je ne comprends toujours pas ce que vous entendez par "capacité à faire plusieurs copies de fichiers source sans copier d'autres fichiers". Une commande rsync modifiée ferait l'affaire, mais ce n'est probablement pas ce que vous voulez dire ...
Tomáš Ehrlich
Je crée généralement dir à l' srcintérieur de la racine du projet. Il s'agit de la copie de travail des fichiers source et de la racine du référentiel git. Je peux faire plusieurs copies de ce répertoire - src, src.bak, src_tmpet ainsi de suite. D' autres dirs non-pension comme env, tmp, media, backuprésident sur le même niveau. Je peux donc à tout cp -r src src.bakmoment faire des expériences avec git ou comparer des versions avec un outil externe. Bien que vous ayez des fichiers locaux à l'intérieur de votre référentiel, j'ai un référentiel à l'intérieur de mon répertoire de fichiers locaux (vice versa). Le meilleur nom de mon srcdir est repo.
raacer
19

Ma réponse est inspirée de ma propre expérience de travail, et principalement dans le livre Two Scoops of Django que je recommande vivement, et où vous pouvez trouver une explication plus détaillée de tout. Je répondrai simplement à certains points, et toute amélioration ou correction sera la bienvenue. Mais il peut aussi y avoir des manières plus correctes d'atteindre le même but.

Projets
J'ai un dossier principal dans mon répertoire personnel où je gère tous les projets sur lesquels je travaille.

Fichiers source
J'utilise personnellement la racine du projet django comme racine du référentiel de mes projets. Mais dans le livre, il est recommandé de séparer les deux choses. Je pense que c'est une meilleure approche, donc j'espère commencer à faire le changement progressivement sur mes projets.

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

Le référentiel
Git ou Mercurial semble être les systèmes de contrôle de version les plus populaires parmi les développeurs Django. Et les services d'hébergement les plus populaires pour les sauvegardes GitHub et Bitbucket .

Environnement virtuel
I utilisation virtualenv virtualenvwrapper. Après avoir installé le second, vous devez configurer votre répertoire de travail. Le mien est sur mon répertoire / home / envs , comme il est recommandé dans le guide d'installation de virtualenvwrapper. Mais je ne pense pas que le plus important soit de savoir où est-il placé. La chose la plus importante lorsque vous travaillez avec des environnements virtuels est de maintenir le fichier requirements.txt à jour.

pip freeze -l > requirements.txt 


Dossier de projet racine statique


Dossier du projet racine multimédia

README
Repository root

LICENCE
Racine du référentiel


Racine du référentiel de documents . Ces packages python peuvent vous aider à simplifier la gestion de votre documentation:

Croquis

Exemples

Base de données

cor
la source
Merci de partager votre expérience. Il y a beaucoup de répertoires 'project *' dans votre structure. Vous n'utilisez probablement pas de tels noms dans la vraie vie, non? Disons que nous avons un projet «todo». Comment nommez-vous ces répertoires dans un tel cas? Le problème que je vois dans votre structure actuelle est de mélanger le référentiel avec des fichiers non référentiels (comme vous l'avez noté ci-dessus). Il peut être ennuyeux d'ajouter une poubelle à .gitignore, n'est-ce pas? Une autre chose douteuse est de garder le répertoire d'environnement si loin du projet lui-même. Est-ce que ça fait du sens? Pourquoi ne pas créer ~ / docs, ~ / statics et ainsi de suite? Même git aime s'asseoir près des fichiers source.
raacer
Je les nommerais: "todo_project" -> todo -> todo (ou peut-être todoapp). Je pense que c'est important d'être le dossier du référentiel à la racine de la hiérarchie des répertoires. Mais, c'est juste mon avis. À propos du répertoire d'environnement, lorsque vous avez besoin de configurer l'environnement de production, vous n'avez qu'à taper: pip install -U -r requirements.txt. Mais, comme je l'ai dit, il n'y a pas une solution pour tout.
cor
Le chemin vers l'application principale est donc "projects / todo_project / todo / todo". Le mot «projets» est répété deux fois et le mot «todo» répété trois fois. Cela ressemble à "projets / projet / mon_projet / rép_projet / projet / projet". Les noms ne sont pas clairs. C'est l'un des problèmes majeurs que j'essaie de résoudre dans ma structure de répertoires. Je souhaite nommer les répertoires pour faciliter la compréhension de la hiérarchie. Qu'en est-il de la racine du référentiel, pourriez-vous s'il vous plaît expliquer pourquoi c'est important? Pourriez-vous également expliquer ce qui est bon de garder les envs en dehors du répertoire principal du projet?
raacer
13

Je n'aime pas créer un nouveau settings/répertoire. J'ajoute simplement des fichiers nommés settings_dev.pyet settings_production.pyje n'ai donc pas à modifier le fichier BASE_DIR. L'approche ci-dessous augmente la structure par défaut au lieu de la modifier.

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

Je pense que ce:

    settings.py
    settings_dev.py
    settings_production.py

c'est mieux que ça:

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

Ce concept s'applique également à d'autres fichiers.


Je place généralement node_modules/et bower_components/dans le répertoire du projet dans le static/dossier par défaut .

Parfois, un vendor/répertoire pour les sous-modules Git, mais généralement je les place dans le static/dossier.

isar
la source
4

Voici ce que je suis sur mon système.

  1. Tous les projets : Il y a un répertoire de projets dans mon dossier personnel, c'est-à-dire ~/projects. Tous les projets reposent à l'intérieur.

  2. Projet individuel : Je suis un modèle de structure standardisé utilisé par de nombreux développeurs appelé django-skel pour des projets individuels. Il prend essentiellement en charge tous vos fichiers statiques et fichiers multimédias et tout.

  3. Environnement virtuel : J'ai un dossier virtualenvs à l'intérieur de ma maison pour stocker tous les environnements virtuels dans le système, c'est-à-dire ~/virtualenvs. Cela me donne la flexibilité que je connais tous les environnements virtuels que j'ai et que je peux utiliser facilement

Les 3 ci-dessus sont les principales partitions de Mon environnement de travail.

Toutes les autres parties que vous avez mentionnées dépendent principalement de projet à projet (c'est-à-dire que vous pouvez utiliser différentes bases de données pour différents projets). Ils devraient donc résider dans leurs projets individuels.

Sahil Kalra
la source
Je vous remercie. Il peut être ennuyeux d'ajouter une corbeille à .gitignore lorsque vous mélangez un référentiel avec des fichiers non référentiels. N'est-ce pas? Certains de mes projets ont jusqu'à dix et plus de tels fichiers et répertoires, donc cela me pose un réel problème. Une autre chose douteuse est de garder le répertoire env si loin du projet lui-même. Quelle est la flexibilité d'une telle solution? Pourquoi ne pas créer ~ / docs, ~ / statics et ainsi de suite? Même git aime s'asseoir près des fichiers source. Je pensais que la flexibilité, c'était quand je pouvais simplement copier / déplacer / archiver / supprimer tout le répertoire de projet, y compris virtualenv, et pouvoir gérer facilement plusieurs envs dans un même projet
raacer
4

Selon le squelette du projet Django, la structure de répertoire appropriée qui pourrait être suivie est:

[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

Reportez-vous à https://django-project-skeleton.readthedocs.io/en/latest/structure.html pour la dernière structure de répertoires.

Sachin Vardhan
la source
7
Je déteste l'approche [projectname] / [projectname]!)
raacer
1
django-project-skeleton n'est pas "la documentation Django". Il serait plus précis de dire "Comme pour django-project-skeleton, ...".
David Winiecki
0

Vous pouvez utiliser le référentiel https://github.com/Mischback/django-project-skeleton .

Exécutez la commande ci-dessous:

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

La structure est quelque chose comme ceci:

[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
Ehsan Barkhordar
la source