Лучшие практики для структуры рабочего каталога проекта Django


176

Я знаю, что на самом деле нет единственно верного пути. Однако я обнаружил, что сложно создать структуру каталогов, которая хорошо работает и остается чистой для каждого разработчика и администратора. В большинстве проектов на github есть некоторая стандартная структура. Но это не показывает способ организовать другие файлы и все проекты на ПК.

Какой самый удобный способ организовать все эти каталоги на компьютере разработчика? Как вы их называете, и как вы подключаете и разворачиваете это на сервере?

  • проекты (все проекты, над которыми вы работаете)
  • исходные файлы (само приложение)
  • рабочая копия репозитория (я использую git)
  • виртуальная среда (я предпочитаю размещать это рядом с проектом)
  • статический корень (для скомпилированных статических файлов)
  • медиа-корень (для загруженных медиа-файлов)
  • ПРОЧТИ МЕНЯ
  • ЛИЦЕНЗИЯ
  • документы
  • эскизы
  • примеры (пример проекта, который использует приложение, предоставленное этим проектом)
  • база данных (в случае использования sqlite)
  • все, что вам обычно нужно для успешной работы над проектом

Проблемы, которые я хочу решить:

  • Хорошие названия каталогов, чтобы их назначение было ясным.
  • Хранение всех файлов проекта (включая virtualenv) в одном месте, так что я могу легко копировать, перемещать, архивировать, удалять весь проект или оценивать использование дискового пространства.
  • Создание нескольких копий некоторых выбранных наборов файлов, таких как целое приложение, репозиторий или virtualenv, с сохранением одной копии других файлов, которые я не хочу клонировать.
  • Развертывание нужного набора файлов на сервере просто путем rsyncing выбрал один каталог.

Ответы:


259

В моем ~/projects/каталоге есть два вида «проектов» Django , оба имеют немного различную структуру:

  • Автономные сайты
  • Сменные приложения

Автономный сайт

В основном частные проекты, но не обязательно. Обычно это выглядит так:

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

настройки

Основные настройки - производственные. Другие файлы (например. staging.py, development.py) Просто импорт все от production.pyи переопределить только необходимые переменные.

Для каждой среды существуют отдельные файлы настроек, например. производство, разработка. В некоторых проектах у меня также есть настройки для тестирования (для тестового бегуна), промежуточные (в качестве проверки перед финальным развертыванием) и настройки Heroku (для развертывания в heroku).

Требования

Я скорее уточняю требования в setup.py напрямую. Только те, которые требуются для разработки / тестирования среды у меня в requirements_dev.txt.

Некоторые сервисы (например, heroku) требуется иметь requirements.txtв корневом каталоге.

setup.py

Полезно при развертывании проекта с использованием setuptools. Это добавляет manage.pyк PATH, так что я могу работать manage.pyнепосредственно ( в любом месте).

Проектные приложения

Я использовал, чтобы поместить эти приложения в project_name/apps/каталог и импортировать их, используя относительный импорт.

Шаблоны / статические / локаль / тестовые файлы

Я поместил эти шаблоны и статические файлы в глобальный каталог templates / static, а не в каждое приложение. Эти файлы обычно редактируются людьми, которых вообще не волнует структура кода проекта или python. Если вы являетесь разработчиком полного стека и работаете в одиночку или в небольшой команде, вы можете создать для каждого приложения шаблоны / статический каталог. Это действительно просто вопрос вкуса.

То же самое относится и к локали, хотя иногда удобно создать отдельный каталог локали.

Обычно тесты лучше размещать внутри каждого приложения, но обычно существует множество интеграционных / функциональных тестов, которые тестируют больше приложений, работающих вместе, поэтому каталог глобальных тестов имеет смысл.

Каталог Tmp

В корне проекта есть временный каталог, исключенный из VCS. Он используется для хранения медиа / статических файлов и базы данных sqlite во время разработки. Все в tmp может быть удалено в любое время без проблем.

Virtualenv

Я предпочитаю virtualenvwrapperи помещаю все вены в ~/.venvsкаталог, но вы можете поместить его внутрь, tmp/чтобы сохранить вместе.

Шаблон проекта

Я создал шаблон проекта для этой установки, django-start-template

развертывание

Развертывание этого проекта следующее:

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

Вы можете использовать rsyncвместо git, но все же вам нужно запустить пакет команд для обновления вашей среды.

Недавно я создал [django-deploy][2]приложение, которое позволяет мне запускать одну команду управления для обновления среды, но я использовал его только для одного проекта, и я все еще экспериментирую с ним.

Эскизы и чертежи

Черновик шаблонов я размещаю внутри глобального templates/каталога. Я думаю, что можно создать папку sketches/в корне проекта, но еще не использовал ее.

Сменное приложение

Эти приложения обычно готовы к публикации с открытым исходным кодом. Я взял пример ниже с Джанго-формы

~/projects/django-app/

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

Название каталогов понятно (надеюсь). Я помещаю тестовые файлы вне каталога приложения, но это действительно не имеет значения. Важно обеспечить READMEи setup.py, поэтому пакет легко устанавливается через pip.


Спасибо! Мне нравится твоя структура. Это дало мне полезные идеи. Хорошие замечания об использовании setup.py для требований и установке manage.py в PATH. Не могли бы вы показать, как вы делаете последнюю вещь? Также хорошее замечание по поводу 'tmp' dir. Я бы предпочел назвать его «местный», тогда у меня могут быть «env», «tmp» и все, что угодно внутри. Это решает проблему слишком большого количества сделок с gitignore. Новая проблема заключается в том, что это имя слишком близко к «локали». Может быть, имеет смысл перенести 'locale' в основное приложение 'project_name', не уверен. Просто не хочу менять структуру из-за дурного имени. Какие-либо предложения?
гонщик

При использовании setup.py добавьте scriptsключевое слово аргумент: github.com/elvard/django-start-template/blob/master/project/… Мне нравится, tmpпотому что он предлагает «что-то временное», которое можно удалить в любое время. Toplevel localedir не требуется, вы можете разместить его где угодно. Мне просто нравится, чтобы это соответствовало директивам static / templates.
Томаш Эрлих

Мое требование сделать несколько копий исходных файлов без копирования других файлов не решается напрямую. Но цель все еще может быть заархивирована с помощью git checkoutили путем исключения только одного dir 'tmp' при клонировании каталога проекта. Таким образом, кажется, что ваша структура отвечает всем требованиям, и она достаточно понятна для использования на регулярной основе без каких-либо сомнений. Я принимаю ваш ответ. Спасибо.
гонщик

Спасибо. Я до сих пор не понимаю, что вы подразумеваете под «способностью делать несколько копий исходных файлов без копирования других файлов». Подправленная команда rsync подойдет, но это, вероятно, не то, что вы имеете в виду ...
Томаш Эрлих

Я обычно создаю srcкаталог внутри корня проекта. Это рабочая копия исходных файлов и корня репозитория git. Я могу сделать несколько копий этого каталога - src, src.bak, src_tmpи так далее. Другие каталоги не-Репо , как env, tmp, media, backupнаходятся на том же уровне. Поэтому я могу в cp -r src src.bakлюбой момент поэкспериментировать с git или сравнить версии с внешним инструментом. В то время как у вас есть локальные файлы внутри вашего хранилища, у меня есть хранилище внутри моего каталога локальных файлов (наоборот). Лучшее имя моего srcрежиссера repo.
гонщик

19

Мой ответ основан на моем собственном опыте работы, и в основном в книге « Два черпака Джанго», которую я очень рекомендую, и где вы можете найти более подробное объяснение всего. Я просто отвечу на некоторые вопросы, и любые улучшения или исправления будут приветствоваться. Но также могут быть более правильные способы достижения той же цели.

Проекты
У меня есть главная папка в моем личном каталоге, где я храню все проекты, над которыми я работаю.

Исходные файлы
Я лично использую корень проекта django в качестве корня репозитория моих проектов. Но в книге рекомендуется разделить обе вещи. Я думаю, что это лучший подход, поэтому я надеюсь начать постепенно вносить изменения в мои проекты.

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

Репозиторий
Git или Mercurial кажется наиболее популярной системой контроля версий среди разработчиков Django. И самые популярные хостинговые сервисы для бэкапов GitHub и Bitbucket .

Виртуальная среда
Я использую virtualenv и virtualenvwrapper. После установки второго вам нужно настроить ваш рабочий каталог. Мой каталог находится в моем / home / envs каталоге, как это рекомендуется в руководстве по установке virtualenvwrapper. Но я не думаю, что самое главное, где это находится. При работе с виртуальными средами важнее всего поддерживать файл require.txt в актуальном состоянии.

pip freeze -l > requirements.txt 


Папка статического корневого проекта


Папка проекта Media Root

README
Корень репозитория

ЛИЦЕНЗИЯ
Корень хранилища


Корень хранилища документов . Эти пакеты Python могут помочь вам упростить управление вашей документацией:

Этюды

Примеры

База данных


Спасибо, что поделились своим опытом. В вашей структуре много каталогов 'project *'. Вы, вероятно, не используете такие имена в реальной жизни, верно? Допустим, у нас есть проект «todo». Как вы называете эти dirs в таком случае? Проблема, которую я вижу в вашей текущей структуре, заключается в смешивании репозитория с файлами, не являющимися репозиториями (как вы отметили выше). Может быть раздражает добавление мусора в .gitignore, не так ли? Еще одна сомнительная вещь - держать каталог env так далеко от самого проекта. Имеет ли это смысл? Почему бы не создать ~ / docs, ~ / statics и так далее? Даже Git любит сидеть рядом с исходными файлами.
гонщик

Я бы назвал их: "todo_project" -> todo -> todo (или, может быть, todoapp). Я думаю, что это важно, потому что папка репозитория находится в корне иерархии директорий. Но это только мое мнение. Что касается каталога среды, когда вам нужно настроить производственную среду, вы просто набираете: pip install -U -r needs.txt. Но, как я уже сказал, не существует единого решения для всего.
кор

Таким образом, путь к основному приложению - "projects / todo_project / todo / todo". Слово «проекты» повторяется дважды, а слово «todo» повторяется три раза. Это выглядит как "проекты / проект / my_project / project_dir / project / project". Имена очень неясны. Это одна из основных проблем, которые я пытаюсь решить в своей структуре каталогов. Я хочу назвать каталоги, чтобы было проще понять иерархию. Как насчет корня хранилища, не могли бы вы объяснить, почему это важно? Также не могли бы вы объяснить, что хорошего в том, чтобы хранить envs за пределами основного каталога проекта?
гонщик

13

Я не люблю создавать новый settings/каталог. Я просто добавить файлы с именем settings_dev.pyи settings_production.pyпоэтому не нужно редактировать BASE_DIR. Приведенный ниже подход увеличивает структуру по умолчанию вместо ее изменения.

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

Я думаю это:

    settings.py
    settings_dev.py
    settings_production.py

лучше чем это:

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

Эта концепция применима и к другим файлам.


Я обычно размещаю node_modules/и bower_components/в каталоге проекта в static/папке по умолчанию .

Иногда vendor/каталог для Git Submodules, но обычно я помещаю их в static/папку.


4

Вот то, что я следую в моей системе.

  1. Все проекты : Существует каталог проектов в моей домашней папке есть ~/projects. Все проекты лежат внутри него.

  2. Индивидуальный проект : я следую стандартному шаблону структуры, используемому многими разработчиками под названием django-skel для отдельных проектов. Это в основном заботится обо всех ваших статических файлах и медиа-файлах и все.

  3. Виртуальная среда : У меня есть virtualenvs папки внутри мой дом , чтобы хранить все виртуальные среды в системе , т.е. ~/virtualenvs. Это дает мне гибкость, что я знаю, что все виртуальные среды у меня есть и может выглядеть легко использовать

Выше 3 являются основными разделами моей рабочей среды.

Все остальные части, которые вы упомянули , в основном зависят от проекта к проекту (т.е. вы можете использовать разные базы данных для разных проектов). Поэтому они должны проживать в своих индивидуальных проектах.


Спасибо. Может быть неприятно добавлять мусор в .gitignore при смешивании репозитория с файлами, не являющимися репозиториями. Не так ли? Некоторые из моих проектов имеют до десяти и более таких файлов и каталогов, поэтому для меня это реальная проблема. Еще одна сомнительная вещь - держать каталог env так далеко от самого проекта. Какова гибкость в таком решении? Почему бы не создать ~ / docs, ~ / statics и так далее? Даже Git любит сидеть рядом с исходными файлами. Я думал, что гибкость заключается в том, что я могу просто скопировать / переместить / архивировать / удалить весь каталог проекта, включая virtualenv, и легко поддерживать несколько envs в одном проекте
raacer

4

Согласно Django Project Skeleton, правильная структура каталогов, которой можно следовать:

[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

Обратитесь к https://django-project-skeleton.readthedocs.io/en/latest/structure.html для получения последней структуры каталогов.


7
Я ненавижу подходы [имя проекта] / [имя проекта]!)
raacer

1
django-project-skeleton - это не «Документация Django». Правильнее было бы сказать «Согласно django-project-скелет, ...».
Дэвид Винецкий

0

Вы можете использовать https://github.com/Mischback/django-project-skeleton репозиторий.

Запустите команду ниже:

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

Структура примерно такая:

[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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.