Best Practice für die Struktur des Arbeitsverzeichnisses des Django-Projekts

173

Ich weiß, dass es eigentlich keinen einzigen richtigen Weg gibt. Ich habe jedoch festgestellt, dass es schwierig ist, eine Verzeichnisstruktur zu erstellen, die gut funktioniert und für jeden Entwickler und Administrator sauber bleibt. In den meisten Projekten auf Github gibt es eine Standardstruktur. Es zeigt jedoch keine Möglichkeit, andere Dateien und alle Projekte auf dem PC zu organisieren.

Was ist der bequemste Weg, um all diese Verzeichnisse auf der Entwicklungsmaschine zu organisieren? Wie benennen Sie sie und wie verbinden Sie sie und stellen sie auf dem Server bereit?

  • Projekte (alle Projekte, an denen Sie arbeiten)
  • Quelldateien (die Anwendung selbst)
  • Arbeitskopie des Repositorys (ich benutze Git)
  • virtuelle Umgebung (ich ziehe es vor, dies in der Nähe des Projekts zu platzieren)
  • statisches Stammverzeichnis (für kompilierte statische Dateien)
  • Medienstamm (für hochgeladene Mediendateien)
  • Liesmich
  • LIZENZ
  • Unterlagen
  • Skizzen
  • Beispiele (ein Beispielprojekt, das die von diesem Projekt bereitgestellte Anwendung verwendet)
  • Datenbank (falls SQLite verwendet wird)
  • alles andere, was Sie normalerweise für eine erfolgreiche Projektarbeit benötigen

Die Probleme, die ich lösen möchte:

  • Gute Namen von Verzeichnissen, damit ihr Zweck klar ist.
  • Bewahren Sie alle Projektdateien (einschließlich virtualenv) an einem Ort auf, damit ich das gesamte Projekt problemlos kopieren, verschieben, archivieren, entfernen oder den Speicherplatzverbrauch schätzen kann.
  • Erstellen mehrerer Kopien einiger ausgewählter Dateigruppen, z. B. der gesamten Anwendung, des Repositorys oder der virtuellen Umgebung, während eine einzelne Kopie anderer Dateien beibehalten wird, die nicht geklont werden sollen.
  • Bereitstellen des richtigen Satzes von Dateien auf dem Server durch einfaches Synchronisieren eines ausgewählten Verzeichnisses.
Raacer
quelle

Antworten:

257

Es gibt zwei Arten von Django "Projekten", die ich in meinem ~/projects/Verzeichnis habe, beide haben eine etwas unterschiedliche Struktur:

  • Eigenständige Websites
  • Steckbare Anwendungen

Eigenständige Website

Meist private Projekte, muss es aber nicht sein. Es sieht normalerweise so aus:

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

die Einstellungen

Die Haupteinstellungen sind Produktionseinstellungen. Andere Dateien (zB. staging.py, development.py) Einfach importiert alles aus production.pyund nur notwendige Variablen außer Kraft setzen.

Für jede Umgebung gibt es separate Einstellungsdateien, z. Produktion, Entwicklung. Ich habe einige Projekte, die ich auch testen (für Test Runner), Staging (als Überprüfung vor der endgültigen Bereitstellung) und Heroku (für die Bereitstellung auf Heroku) Einstellungen.

Bedarf

Ich spezifiziere die Anforderungen eher direkt in setup.py. Nur die für die Entwicklungs- / Testumgebung erforderlichen, in der ich mich befinde requirements_dev.txt.

Einige Dienste (z. B. Heroku) müssen requirements.txtim Stammverzeichnis vorhanden sein.

setup.py

Nützlich beim Bereitstellen von Projekten mit setuptools. Sie fügt hinzu , manage.pyzu PATH, so dass ich laufen kann manage.py(überall) direkt.

Projektspezifische Apps

Ich habe diese Apps in ein project_name/apps/Verzeichnis gestellt und sie mit relativen Importen importiert.

Templates / static / locale / tests files

Ich habe diese Vorlagen und statischen Dateien in einem globalen Vorlagen- / statischen Verzeichnis abgelegt, nicht in jeder App. Diese Dateien werden normalerweise von Personen bearbeitet, denen Projektstruktur oder Python überhaupt nicht wichtig sind. Wenn Sie ein Full-Stack-Entwickler sind, der alleine oder in einem kleinen Team arbeitet, können Sie pro App Vorlagen / statisches Verzeichnis erstellen. Es ist wirklich nur eine Frage des Geschmacks.

Gleiches gilt für das Gebietsschema, obwohl es manchmal praktisch ist, ein separates Gebietsschemaverzeichnis zu erstellen.

Tests sind normalerweise besser in jeder App zu platzieren, aber normalerweise gibt es viele Integrations- / Funktionstests, bei denen mehr Apps zusammenarbeiten, sodass ein globales Testverzeichnis sinnvoll ist.

Tmp-Verzeichnis

Im Projektstamm befindet sich ein temporäres Verzeichnis, das von VCS ausgeschlossen ist. Es wird verwendet, um Medien- / statische Dateien und SQLite-Datenbanken während der Entwicklung zu speichern. Alles in tmp konnte jederzeit problemlos gelöscht werden.

Virtualenv

Ich bevorzuge virtualenvwrapperund lege alle venvs in ein ~/.venvsVerzeichnis, aber du könntest es hineinlegen tmp/, um es zusammen zu halten.

Projektvorlage

Ich habe eine Projektvorlage für dieses Setup erstellt, die Django-Start-Vorlage

Einsatz

Die Bereitstellung dieses Projekts erfolgt wie folgt:

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

Sie können rsyncanstelle von verwenden git, müssen jedoch eine Reihe von Befehlen ausführen, um Ihre Umgebung zu aktualisieren.

Kürzlich habe ich eine [django-deploy][2]App erstellt, mit der ich einen einzelnen Verwaltungsbefehl ausführen kann, um die Umgebung zu aktualisieren. Ich habe sie jedoch nur für ein Projekt verwendet und experimentiere immer noch damit.

Skizzen und Entwürfe

Entwurf von Vorlagen, die ich in ein globales templates/Verzeichnis lege . Ich denke, man kann einen Ordner sketches/im Projektstamm erstellen , hat ihn aber noch nicht verwendet.

Steckbare Anwendung

Diese Apps sind normalerweise für die Veröffentlichung als Open Source vorbereitet. Ich habe unten ein Beispiel aus Django-Forme genommen

~/projects/django-app/

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

Der Name der Verzeichnisse ist klar (hoffe ich). Ich habe Testdateien außerhalb des App-Verzeichnisses abgelegt, aber das spielt wirklich keine Rolle. Es ist wichtig, READMEund bereitzustellen setup.py, damit das Paket einfach über installiert werden kann pip.

Tomáš Ehrlich
quelle
Danke dir! Ich mag deine Struktur. Es gab mir nützliche Ideen. Gute Punkte zur Verwendung von setup.py für Anforderungen und zur Installation von manage.py in PATH. Könnten Sie bitte zeigen, wie Sie das Letzte tun? Auch ein guter Punkt über 'tmp' dir. Ich würde es lieber "lokal" nennen, dann könnte ich "env", "tmp" und alles auch drinnen haben. Dies löst das Problem, zu viele Geschäfte mit Gitignore zu machen. Ein neues Problem ist, dass dieser Name zu nahe am Gebietsschema liegt. Vielleicht ist es sinnvoll, 'locale' in die Kern-App 'project_name' zu verschieben, nicht sicher. Ich möchte nur nicht die Struktur wegen schlechten Rufs ändern. Irgendwelche Vorschläge?
Raacer
Fügen Sie bei Verwendung von setup.py ein scriptsSchlüsselwortargument hinzu: github.com/elvard/django-start-template/blob/master/project/… Ich mag es, tmpweil es "etwas Temporäres" vorschlägt, das jederzeit entfernt werden kann. Toplevel localedir ist nicht notwendig, du kannst es überall platzieren. Ich mag es einfach, wenn es mit statischen / Vorlagen-Verzeichnissen übereinstimmt.
Tomáš Ehrlich
Meine Anforderung, mehrere Kopien von Quelldateien erstellen zu können, ohne andere Dateien zu kopieren, wird nicht direkt gelöst. Das Ziel kann jedoch weiterhin archiviert werden, indem git checkoutbeim Klonen des Projektverzeichnisses nur ein Verzeichnis 'tmp' verwendet oder ausgeschlossen wird. Es scheint also, dass Ihre Struktur alle Anforderungen erfüllt und klar genug ist, um ohne Zweifel regelmäßig verwendet zu werden. Ich akzeptiere deine Antwort. Danke dir.
Raacer
Danke dir. Ich verstehe immer noch nicht, was Sie unter "Fähigkeit, mehrere Kopien von Quelldateien zu erstellen, ohne andere Dateien zu kopieren" verstehen. Ein optimierter rsync-Befehl würde ausreichen, aber das ist wahrscheinlich nicht das, was Sie meinen ...
Tomáš Ehrlich
Normalerweise erstelle ich ein Verzeichnis srcinnerhalb des Projektstamms. Dies ist die Arbeitskopie der Quelldateien und des Git-Repository-Stamms. Ich kann mehrere Kopien dieses Verzeichnis machen - src, src.bak, src_tmpund so weiter. Andere nicht-Repo - dirs wie env, tmp, media, backupauf dem gleichen Niveau. So kann ich cp -r src src.bakjederzeit mit git experimentieren oder Versionen mit einem externen Tool vergleichen. Während Sie lokale Dateien in Ihrem Repository haben, habe ich Repository in meinem lokalen Dateiverzeichnis (umgekehrt). Der bessere Name meines srcVerzeichnisses ist repo.
Raacer
19

Meine Antwort basiert auf meiner eigenen Arbeitserfahrung und hauptsächlich auf dem Buch Two Scoops of Django, das ich sehr empfehlen kann und in dem Sie eine detailliertere Erklärung für alles finden. Ich werde nur einige der Punkte beantworten, und jede Verbesserung oder Korrektur wird begrüßt. Es kann aber auch korrektere Manieren geben, um den gleichen Zweck zu erreichen.

Projekte
Ich habe einen Hauptordner in meinem persönlichen Verzeichnis, in dem ich alle Projekte verwalte, an denen ich arbeite.

Quelldateien
Ich persönlich benutze die django Projekt Wurzel als Repository Wurzel meiner Projekte. Aber in dem Buch wird empfohlen, beide Dinge zu trennen. Ich denke, dass dies ein besserer Ansatz ist, und hoffe, dass ich meine Projekte schrittweise ändern kann.

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 oder Mercurial scheinen die beliebtesten Versionskontrollsysteme unter Django-Entwicklern zu sein. Und die beliebtesten Hosting-Dienste für Backups GitHub und Bitbucket .

Virtuelle Umgebung
Ich verwende virtualenv und virtualenvwrapper. Nach der Installation des zweiten müssen Sie Ihr Arbeitsverzeichnis einrichten. Meins befindet sich in meinem Verzeichnis / home / envs , wie im Installationshandbuch für virtualenvwrapper empfohlen. Aber ich denke nicht, dass das Wichtigste ist, wo es platziert wird. Das Wichtigste bei der Arbeit mit virtuellen Umgebungen ist, die Datei require.txt auf dem neuesten Stand zu halten.

pip freeze -l > requirements.txt 

Statischer
Stammprojektordner


Ordner " Media Root Project"

README
Repository-Stammverzeichnis

LICENSE
Repository-Stammverzeichnis

Dokumenten-
Repository-Stammverzeichnis. Diese Python-Pakete können Ihnen dabei helfen, die Verwaltung Ihrer Dokumentation zu vereinfachen:

Skizzen

Beispiele

Datenbank

cor
quelle
Vielen Dank für Ihre Erfahrungen. In Ihrer Struktur befinden sich viele Projektverzeichnisse. Sie verwenden solche Namen wahrscheinlich nicht im wirklichen Leben, oder? Nehmen wir an, wir haben ein "ToDo" -Projekt. Wie nennt man diese Verzeichnisse in einem solchen Fall? Das Problem, das ich in Ihrer aktuellen Struktur sehe, ist das Mischen von Repository mit Nicht-Repository-Dateien (wie Sie oben erwähnt haben). Es kann ärgerlich sein, .gitignore Müll hinzuzufügen, nicht wahr? Eine andere zweifelhafte Sache ist, die Umgebung so weit vom Projekt selbst entfernt zu halten. Macht das Sinn? Warum nicht ~ / docs, ~ / statics usw. erstellen? Sogar Git sitzt gerne in der Nähe der Quelldateien.
Raacer
Ich würde sie nennen: "todo_project" -> todo -> todo (oder vielleicht todoapp). Ich denke, dass es wichtig ist, den Repository-Ordner im Stammverzeichnis der Verzeichnishierarchie zu haben. Aber ist nur meine Meinung. Informationen zum Umgebungsverzeichnis: Wenn Sie die Produktionsumgebung einrichten müssen, geben Sie einfach Folgendes ein: pip install -U -r require.txt. Aber wie gesagt, es gibt nicht für alles eine Lösung.
Cor
Der Pfad zur Haupt-App lautet also "projects / todo_project / todo / todo". Das Wort "Projekte" wurde zweimal wiederholt, und das Wort "Aufgaben" wurde dreimal wiederholt. Dies scheint "Projekte / Projekt / mein_Projekt / Projektverzeichnis / Projekt / Projekt". Die Namen sind sehr unklar. Dies ist eines der Hauptprobleme, die ich in meiner Verzeichnisstruktur zu lösen versuche. Ich möchte die Verzeichnisse benennen, um das Verständnis der Hierarchie zu erleichtern. Was ist mit dem Repository-Stammverzeichnis? Können Sie bitte erklären, warum dies wichtig ist? Könnten Sie bitte auch erklären, was gut daran ist, envs außerhalb des Hauptprojektverzeichnisses zu halten?
Raacer
13

Ich möchte kein neues settings/Verzeichnis erstellen . Ich füge einfach Dateien mit dem Namen hinzu settings_dev.pyund settings_production.pymuss die nicht bearbeiten BASE_DIR. Der folgende Ansatz erhöht die Standardstruktur, anstatt sie zu ändern.

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

Ich denke das:

    settings.py
    settings_dev.py
    settings_production.py

ist besser als das:

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

Dieses Konzept gilt auch für andere Dateien.


Normalerweise platziere ich node_modules/und bower_components/im Projektverzeichnis innerhalb des Standardordners static/.

Irgendwann ein vendor/Verzeichnis für Git-Submodule, aber normalerweise lege ich sie in den static/Ordner.

isar
quelle
4

Folgendes folge ich auf meinem System.

  1. Alle Projekte : In meinem Home-Ordner befindet sich ein Projektverzeichnis, d ~/projects. H. Alle Projekte ruhen darin.

  2. Einzelprojekt : Ich folge einer standardisierten Strukturvorlage, die von vielen Entwicklern als Django-Skel für Einzelprojekte verwendet wird. Es kümmert sich im Grunde um alle Ihre statischen Dateien und Mediendateien und alles.

  3. Virtuelle Umgebung : Ich habe einen Ordner für virtuelle Umgebungen in meinem Haus, in dem alle virtuellen Umgebungen im System gespeichert werden können ~/virtualenvs. Dies gibt mir die Flexibilität, dass ich weiß, welche virtuellen Umgebungen ich habe und wie sie einfach aussehen können

Die obigen 3 sind die Hauptpartitionen meiner Arbeitsumgebung.

Alle anderen Teile, die Sie erwähnt haben, hängen hauptsächlich von Projekt zu Projekt ab (dh Sie können unterschiedliche Datenbanken für unterschiedliche Projekte verwenden). Sie sollten also in ihren einzelnen Projekten wohnen.

Sahil Kalra
quelle
Danke dir. Es kann ärgerlich sein, Papierkorb zu .gitignore hinzuzufügen, wenn Repository mit Nicht-Repository-Dateien gemischt wird. Oder nicht? Einige meiner Projekte haben bis zu zehn und mehr solcher Dateien und Verzeichnisse, was für mich ein echtes Problem darstellt. Eine andere zweifelhafte Sache ist, die Umgebung so weit vom Projekt selbst entfernt zu halten. Was ist die Flexibilität in einer solchen Lösung? Warum nicht ~ / docs, ~ / statics usw. erstellen? Sogar Git sitzt gerne in der Nähe der Quelldateien. Ich dachte, Flexibilität ist, wenn ich einfach das gesamte Projektverzeichnis einschließlich virtualenv kopieren / verschieben / archivieren / entfernen kann und problemlos mehrere Envs innerhalb eines Projekts verwalten kann
raacer
4

Gemäß dem Django-Projektskelett ist die richtige Verzeichnisstruktur, die befolgt werden kann:

[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

Die neueste Verzeichnisstruktur finden Sie unter https://django-project-skeleton.readthedocs.io/en/latest/structure.html .

Sachin Vardhan
quelle
7
Ich hasse den Ansatz [Projektname] / [Projektname]!)
Raacer
1
Das Django-Projekt-Skelett ist nicht "die Django-Dokumentation". Es wäre genauer zu sagen "Nach Django-Projekt-Skelett, ...".
David Winiecki
0

Sie können das https://github.com/Mischback/django-project-skeleton Repository verwenden.

Führen Sie den folgenden Befehl aus:

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

Die Struktur ist ungefähr so:

[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
quelle