Praktik terbaik untuk struktur direktori kerja proyek Django

174

Saya tahu sebenarnya tidak ada satu pun cara yang benar. Namun saya menemukan bahwa sulit untuk membuat struktur direktori yang berfungsi dengan baik dan tetap bersih untuk setiap pengembang dan administrator. Ada beberapa struktur standar di sebagian besar proyek di github. Tetapi tidak menunjukkan cara untuk mengatur file lain dan semua proyek di pc.

Apa cara paling nyaman untuk mengatur semua direktori ini pada mesin pengembangan? Bagaimana Anda menamai mereka, dan bagaimana Anda menghubungkan dan menggunakan ini ke server?

  • proyek (semua proyek yang sedang Anda kerjakan)
  • file sumber (aplikasi itu sendiri)
  • copy repositori yang berfungsi (saya menggunakan git)
  • lingkungan virtual (saya lebih suka menempatkan ini di dekat proyek)
  • root statis (untuk file statis terkompilasi)
  • root media (untuk file media yang diunggah)
  • Baca aku
  • LISENSI
  • dokumen
  • sketsa
  • contoh (contoh proyek yang menggunakan aplikasi yang disediakan oleh proyek ini)
  • database (dalam kasus sqlite digunakan)
  • hal lain yang biasanya Anda butuhkan untuk pekerjaan yang berhasil pada proyek

Masalah yang ingin saya pecahkan:

  • Nama direktori yang bagus sehingga tujuannya jelas.
  • Menyimpan semua file proyek (termasuk virtualenv) di satu tempat, jadi saya dapat dengan mudah menyalin, memindahkan, mengarsipkan, menghapus seluruh proyek atau memperkirakan penggunaan ruang disk.
  • Membuat banyak salinan dari beberapa set file yang dipilih seperti seluruh aplikasi, repositori atau virtualenv, sambil menyimpan satu salinan file lain yang tidak ingin saya tiru.
  • Menyebarkan set file ke server hanya dengan rsyncing satu dir yang dipilih.
raacer
sumber

Jawaban:

257

Ada dua jenis "proyek" Django yang saya miliki di ~/projects/direktori saya , keduanya memiliki struktur yang sedikit berbeda .:

  • Situs web yang berdiri sendiri
  • Aplikasi yang dapat dicolokkan

Situs web yang berdiri sendiri

Sebagian besar proyek pribadi, tetapi tidak harus. Biasanya terlihat seperti ini:

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

Pengaturan

Pengaturan utama adalah pengaturan produksi. File lain (mis. staging.py, development.py) Cukup mengimpor semuanya dari production.pydan mengabaikan hanya variabel yang diperlukan.

Untuk setiap lingkungan, ada file pengaturan terpisah, mis. produksi, pengembangan. Saya beberapa proyek saya juga menguji (untuk test runner), pementasan (sebagai cek sebelum penyebaran akhir) dan pengaturan heroku (untuk penempatan ke heroku).

Persyaratan

Saya lebih suka menentukan persyaratan di setup.py secara langsung. Hanya yang diperlukan untuk lingkungan pengembangan / pengujian yang saya miliki requirements_dev.txt.

Beberapa layanan (mis. Heroku) harus ada requirements.txtdi direktori root.

setup.py

Berguna saat menggunakan proyek menggunakan setuptools. Ia menambahkan manage.pyuntuk PATH, jadi saya dapat menjalankan manage.pylangsung (di mana saja).

Aplikasi khusus proyek

Saya biasa meletakkan aplikasi ini ke project_name/apps/direktori dan mengimpornya menggunakan impor relatif.

Template / file statis / lokal / tes

Saya menempatkan template dan file statis ini ke template global / direktori statis, bukan di dalam setiap aplikasi. File-file ini biasanya diedit oleh orang-orang, yang tidak peduli dengan struktur kode proyek atau python sama sekali. Jika Anda adalah pengembang tumpukan penuh yang bekerja sendiri atau dalam tim kecil, Anda dapat membuat templat per-aplikasi / direktori statis. Ini benar-benar hanya masalah selera.

Hal yang sama berlaku untuk lokal, meskipun kadang-kadang lebih nyaman untuk membuat direktori lokal terpisah.

Tes biasanya lebih baik untuk ditempatkan di dalam setiap aplikasi, tetapi biasanya ada banyak tes integrasi / fungsional yang menguji lebih banyak aplikasi yang bekerja bersama, sehingga direktori tes global memang masuk akal.

Direktori tmp

Ada direktori sementara di root proyek, dikecualikan dari VCS. Ini digunakan untuk menyimpan file media / statis dan database sqlite selama pengembangan. Semua yang ada di tmp dapat dihapus kapan saja tanpa masalah.

Virtualenv

Saya lebih suka virtualenvwrapperdan menempatkan semua vv ke ~/.venvsdirektori, tetapi Anda bisa menempatkannya di dalam tmp/untuk menyimpannya.

Template proyek

Saya telah membuat template proyek untuk pengaturan ini, django-start-template

Penyebaran

Penerapan proyek ini adalah sebagai berikut:

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

Anda dapat menggunakan rsyncalih-alih git, tetapi tetap saja Anda harus menjalankan banyak perintah untuk memperbarui lingkungan Anda.

Baru-baru ini, saya membuat [django-deploy][2]aplikasi, yang memungkinkan saya menjalankan perintah manajemen tunggal untuk memperbarui lingkungan, tetapi saya telah menggunakannya untuk satu proyek saja dan saya masih bereksperimen dengannya.

Sketsa dan konsep

Draft template yang saya tempatkan di dalam templates/direktori global . Saya kira orang dapat membuat folder sketches/di root proyek, tetapi belum menggunakannya.

Aplikasi Pluggable

Aplikasi ini biasanya disiapkan untuk dipublikasikan sebagai sumber terbuka. Saya telah mengambil contoh di bawah ini dari django-forme

~/projects/django-app/

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

Nama direktori jelas (saya harap). Saya meletakkan file uji di luar direktori aplikasi, tetapi sebenarnya tidak masalah. Sangat penting untuk menyediakan READMEdan setup.py, sehingga paket mudah diinstal melalui pip.

Tomáš Ehrlich
sumber
Terima kasih! Saya suka struktur Anda. Itu memberi saya ide yang berguna. Poin bagus tentang menggunakan setup.py untuk persyaratan dan menginstal manage.py ke PATH. Bisakah Anda menunjukkan bagaimana Anda melakukan hal terakhir? Juga bagus tentang dir 'tmp'. Saya lebih suka menamainya 'lokal', maka saya mungkin memiliki 'env', 'tmp' dan apa pun juga di dalamnya. Ini menyelesaikan masalah terlalu banyak berurusan dengan gitignore. Masalah baru adalah bahwa nama ini terlalu dekat dengan 'lokal'. Mungkin masuk akal untuk memindahkan 'lokal' ke aplikasi inti 'project_name', tidak yakin. Hanya saja, tidak ingin mengubah struktur karena nama yang buruk. Ada saran?
raacer
Saat menggunakan setup.py, tambahkan scriptsargumen kata kunci: github.com/elvard/django-start-template/blob/master/project/... Saya suka tmpkarena menyarankan "sesuatu sementara" yang dapat dihapus kapan saja. Toplevel localedir tidak perlu, Anda bisa meletakkannya di mana saja. Saya hanya ingin konsisten dengan dirs statis / template.
Tomáš Ehrlich
Persyaratan saya untuk kemampuan membuat beberapa salinan file sumber tanpa menyalin file lain tidak terpecahkan secara langsung. Tetapi tujuannya masih dapat diarsipkan dengan menggunakan git checkoutatau dengan mengecualikan hanya satu dir 'tmp' ketika kloning direktori proyek. Jadi sepertinya struktur Anda memenuhi semua persyaratan, dan cukup jelas untuk digunakan secara teratur tanpa keraguan. Saya menerima jawaban Anda. Terima kasih.
raacer
Terima kasih. Saya masih tidak mengerti apa yang Anda maksud dengan "kemampuan untuk membuat beberapa salinan file sumber tanpa menyalin file lain". Perintah rsync tweak akan berhasil, tapi itu mungkin bukan yang Anda maksud ...
Tomáš Ehrlich
Saya biasanya membuat dir srcdi dalam root proyek. Ini adalah copy pekerjaan file sumber dan root repositori git. Aku bisa membuat beberapa salinan dari direktori ini - src, src.bak, src_tmpdan sebagainya. Lainnya dirs non-repo seperti env, tmp, media, backupberada pada tingkat yang sama. Jadi saya bisa cp -r src src.bakkapan saja saya ingin melakukan percobaan dengan git atau membandingkan versi dengan alat eksternal. Meskipun Anda memiliki file lokal di dalam repositori Anda, saya memiliki repositori di dalam dir file lokal saya (sebaliknya). Nama yang lebih baik dari srcdir saya adalah repo.
raacer
19

Jawaban saya terinspirasi oleh pengalaman kerja saya sendiri, dan sebagian besar dalam buku Two Scoops of Django yang sangat saya rekomendasikan, dan di mana Anda dapat menemukan penjelasan yang lebih rinci tentang semuanya. Saya hanya akan menjawab beberapa poin, dan perbaikan atau koreksi akan disambut. Tetapi ada juga perilaku yang lebih benar untuk mencapai tujuan yang sama.

Proyek
Saya memiliki folder utama di direktori pribadi saya tempat saya memelihara semua proyek tempat saya bekerja.

File Sumber
Saya pribadi menggunakan root proyek Django sebagai root repositori proyek saya. Namun dalam buku ini dianjurkan untuk memisahkan kedua hal tersebut. Saya pikir ini adalah pendekatan yang lebih baik, jadi saya berharap untuk mulai membuat perubahan secara progresif pada proyek saya.

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 atau Mercurial tampaknya menjadi sistem kontrol versi paling populer di kalangan pengembang Django. Dan layanan hosting paling populer untuk backup GitHub dan Bitbucket .

Lingkungan Virtual
Saya menggunakan virtualenv dan virtualenvwrapper. Setelah menginstal yang kedua, Anda perlu mengatur direktori kerja Anda. Saya adalah pada saya / home / envs direktori, seperti yang disarankan pada panduan instalasi virtualenvwrapper. Tapi saya tidak berpikir yang paling penting adalah di mana ia ditempatkan. Yang paling penting ketika bekerja dengan lingkungan virtual adalah menjaga agar file needs.txt tetap terbarui.

pip freeze -l > requirements.txt 


Folder Static Root Project


Folder Media Root Project


Root Repositori README

LICENSE
Root repositori


Root Repositori Dokumen . Paket python ini dapat membantu Anda membuat dokumentasi Anda lebih mudah:

Sketsa

Contohnya

Basis data

cor
sumber
Terima kasih telah berbagi pengalaman Anda. Ada banyak direktori 'proyek *' dalam struktur Anda. Anda mungkin tidak menggunakan nama seperti itu di kehidupan nyata, bukan? Katakanlah kita memiliki proyek 'todo'. Bagaimana Anda memberi nama dir ini dalam kasus seperti itu? Masalah yang saya lihat dalam struktur Anda saat ini adalah mencampur repositori dengan file non-repositori (seperti yang Anda sebutkan di atas). Mungkin mengganggu menambahkan sampah ke .gitignore, bukan? Hal lain yang meragukan adalah menjaga env dir sejauh dari proyek itu sendiri. Apakah masuk akal? Mengapa tidak membuat ~ / docs, ~ / statika dan sebagainya? Bahkan git suka duduk di dekat file sumber.
raacer
Saya akan menamainya: "todo_project" -> todo -> todo (atau mungkin todoapp). Saya pikir itu penting karena folder repositori di root hierarki direcectory. Tapi, itu hanya pendapat saya. Tentang direktori lingkungan, ketika Anda perlu mengatur lingkungan produksi, Anda selesai dengan mengetikkan saja: pip install -U -r requirement.txt. Tetapi, seperti yang saya katakan, tidak ada satu solusi untuk semuanya.
kor
Jadi jalur ke aplikasi utama adalah "proyek / todo_project / todo / todo". Kata "proyek" diulang dua kali, dan kata "todo" diulang tiga kali. Ini sepertinya "proyek / proyek / my_project / project_dir / proyek / proyek". Nama-nama itu sangat tidak jelas. Ini adalah salah satu masalah utama yang saya coba pecahkan dalam struktur direktori saya. Saya ingin memberi nama direktori untuk memudahkan memahami hierarki. Bagaimana dengan root repositori, bisakah Anda menjelaskan mengapa ini penting? Bisakah Anda jelaskan apa yang baik tentang menjaga envs di luar dir proyek utama?
raacer
13

Saya tidak suka membuat settings/direktori baru . Saya cukup menambahkan file bernama settings_dev.pydan settings_production.pyjadi saya tidak perlu mengedit BASE_DIR. Pendekatan di bawah ini meningkatkan struktur default alih-alih mengubahnya.

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

Saya pikir ini:

    settings.py
    settings_dev.py
    settings_production.py

lebih baik dari ini:

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

Konsep ini berlaku untuk file lain juga.


Saya biasanya menempatkan node_modules/dan bower_components/dalam direktori proyek di dalam static/folder default .

Suatu vendor/direktori untuk Git Submodules tetapi biasanya saya menempatkannya di static/folder.

isar
sumber
4

Inilah yang saya ikuti di sistem saya.

  1. Semua Proyek : Ada direktori proyek di folder rumah saya yaitu ~/projects. Semua proyek ada di dalamnya.

  2. Proyek Perorangan : Saya mengikuti templat struktur standar yang digunakan oleh banyak pengembang yang disebut Django-skel untuk proyek perorangan. Ini pada dasarnya menangani semua file statis dan file media dan semua.

  3. Lingkungan virtual : Saya memiliki folder virtualenvs di dalam rumah saya untuk menyimpan semua lingkungan virtual dalam sistem ~/virtualenvs. Ini memberi saya fleksibilitas bahwa saya tahu semua lingkungan virtual yang saya miliki dan dapat terlihat mudah digunakan

3 di atas adalah partisi utama dari lingkungan kerja saya.

Semua bagian lain yang Anda sebutkan sebagian besar bergantung pada proyek ke proyek (yaitu Anda mungkin menggunakan database berbeda untuk proyek yang berbeda). Jadi mereka harus tinggal di proyek masing-masing.

Sahil kalra
sumber
Terima kasih. Mungkin menjengkelkan untuk menambahkan sampah ke .gitignore saat menggabungkan repositori dengan file non-repositori. Bukankah begitu? Beberapa proyek saya memiliki hingga sepuluh dan lebih banyak file dan dir, jadi ini membuat masalah bagi saya. Hal lain yang meragukan adalah menjaga env dir sejauh dari proyek itu sendiri. Apa fleksibilitas dalam solusi semacam itu? Mengapa tidak membuat ~ / docs, ~ / statika dan sebagainya? Bahkan git suka duduk di dekat file sumber. Saya pikir fleksibilitas adalah ketika saya hanya bisa menyalin / memindahkan / mengarsipkan / menghapus seluruh direktori proyek termasuk virtualenv dan dapat mempertahankan beberapa env dalam satu proyek dengan mudah
raacer
4

Sesuai kerangka proyek Django, struktur direktori yang tepat yang dapat diikuti adalah:

[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

Rujuk https://django-project-skeleton.readthedocs.io/en/latest/structure.html untuk struktur direktori terbaru.

Sachin Vardhan
sumber
7
Saya benci pendekatan [projectname] / [projectname]!)
raacer
1
django-project-skeleton bukanlah "Dokumentasi Django". Akan lebih akurat untuk mengatakan "Sesuai kerangka-proyek-kerangka, ...".
David Winiecki
0

Anda dapat menggunakan https://github.com/Mischback/django-project-skeleton repository.

Jalankan perintah di bawah ini:

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

Strukturnya kira-kira seperti ini:

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