hexvolt-блог: Django Workflow. Организация рабочего процесса.


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Освоение Ubuntu, Python , Django, PostgreSQL и не только

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Django Workflow. Организация рабочего процесса.

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

 


Общая концепция


Очевидно, что процесс разработки лучше всего вести на локальной машине (обычно в контесте разработки ее называют development-машиной): здесь есть и любимая версия Linux ОС, и любой удобный софт, и возможность работы без Интернета, да и производительность, как правило, на порядок выше, чем при работе с удаленным компом через какой-либо сетевой протокол. Удаленный же "боевой" сервер, на котором будет работать наш Django-проект, обычно называется production-сервером. Это два ключевых понятия. Итак, процесс разработки мы ведем дома на девелопмент-машине, а по мере создания более-менее рабочих версий проекта, будем выкладывать их на продакшн.



Что касается организации локального рабочего места, то ниже (п. 0) будет показан список рекомендуемых к установке программ. Здесь же я хотел бы выделить самый важный инструмент из них — это система контроля версий Git. В сети много информации о ней, если в двух словах — Git позволяет вести историю изменений всех файлов проекта, откатываться до любой из предыдущих версий проекта, организовывать командную работу, синхронизировать изменения, сделанные разными пользователями в одном и том же проекте, создавать репозитории для распространения вашего проекта и т.д. По сути, Git (и аналогичные ему системы контроля версий) стали своего рода стандартом ведения проектов, поэтому крайне рекомендуется сразу организовывать работу через Git, даже если вы будете вести свой сайт сами и не будете ни с кем делиться. Таким образом, использование Git позволяет убить сразу нескольких зайцев — разработчик может не бояться потерять предыдущие версии своего кода, отпадает необходимость в резервных копиях, и появляется возможность расшаривать и синхроинзировать свой проект в случае командной разработки.



И последний момент. Система контроля версий Git обычно связана с использованием удаленного Git-сервера (например, BitBucket, GitHub), на который осуществляется выгрузка локального проекта (с целью расшаривания его другим пользователям, портирования на другие компьютеры или просто с целью хранения исходников "на облаке"). С учетмо этого, общий принцип работы над Django-проектом может выглядеть примерно так:


  • редактируем код на девелопмент-машине
  • выгружаем проект (операция push) с локальной машины на Git-сервер
  • когда нужно развернуть проект на "боевом" сервере, то скачиваем наш проект (операция pull) с Git-сервера на продакшн-машину.



Если есть необходимость работать над своим проектом, например, дома и на работе, то процесс может выглядеть так:


  • редактируем код на домашней девелопмент-машине
  • перед уходом на работу выгружаем наш проект на Git-сервер
  • находясь на работе, скачиваем последнюю версию своего проекта с Git-сервера на рабочую девелопмент-машину
  • редактируем код на работе, перед уходом домой снова выгружаем уже новую версию проекта на Git-сервер
  • дома забираем ее с Git-сервера на домашнюю девелопмент-машину и т.д.
  • когда же нужно развернуть проект на "боевом" сервере, скачиваем его с Git-сервера на продакшн-сервер



Ниже приведен список рекомендуемого ПО, которое нужно установить перед началом работы и на примере показана последовательность подготовки рабочего места, организации директорий и пр.


0. Подготовка к началу работы

В системе (глобально) должны быть установлены:
Итак, после всех приготовлений, исходное состояние нашей девелопмент-машины следующее. В домашней директории есть традиционная папка для виртуальных окружений (~/.virtualenvs), а также папка для хранения исходников проекта (я ее называю ~/projects_dev). Причем, про существование первой папки, в принципе, можно забыть (не даром она скрытая, с ней автоматом будет работать virtualenv в фоновом режиме).


Приступаем к работе над новым проектом под названием django1.


1. Создаем виртуальное окружение для проекта

    mkvirtualenv django1



Неважно, где именно вызвана эта команда — в папке .virtualenvs создасться и автоматически активируется виртуальное окружение django1.


2. Устанавливаем Django и создаем новый проект

Находясь в активированном окружении (django1), устанавливаем в него фреймворк django:

    pip install django



После установки фреймворка, создаем наш джанго-проект, располагая его в папке projects_dev:

    cd ~/projects_dev/

    django-admin.py startproject django1


3. Создаем структуру директорий django

Итак, после создания пустого проекта имеем следующую структуру директорий:
.

└── django1

    ├── django1

    │   ├── __init__.py

    │   ├── settings.py

    │   ├── urls.py

    │   └── wsgi.py

    └── manage.py

Какие папки и файлы нам понадобятся и где их расположить? 
а) Во-первых, понадобится файл README.rst с описанием нашего проекта. Поскольку он касается всего проекта, располагаем его в корне, возле файла manage.py.

Примечание: .rst — это расширение файла, составленного на облегченном языке разметки. Такой язык с одной стороны понятен читателю и не захламлен тэгами, как HTML, а сдругой стороны позволяет красиво форматировать текст тем сервисам, которые понимают этот язык. Одним из таких сервисов, в том числе, является bitbucket, поэтому такой формат файла является оптимальным выбором и, своего рода, стандартом.

б) Понадобится папка requirements, где будут храниться файлы, генерируемые командой "pip freeze" (файлы, содержащие список пакетов, требуемых для работы нашего проекта). Почему именно папка, а не просто один файл? Потому что для разработчика (девелопмент-машины) обычно нужен один набор пакетов, а для сервера (продакшн-машины) — другой. Поэтому в папке можно насоздавать несколько файлов для тех или иных нужд. Создаем эту папку тоже в корне проекта:

.
└── django1
    ├── django1
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── requirements
    ├── manage.py
    └── README.rst

в) В корне проекта создаем папки media/ и static/ для хранения статических файлов (css, jpg, js и т.д.). Причем, это те самые папки, куда будет автоматически собираться статика командой collectstatic. Именно на них будут ссылаться переменные STATIC_ROOT и MEDIA_ROOT в django. Следует отметить, что в пределах каждого django-приложения, как правило, есть своя локальная папка static, содержащая статику для конкретного приложения. Системная команда collectstatic в процессе сбора статики будет обходить эти папки и копировать всю статику в root-папку static/. Поэтому создаваемые в корне проекта директории будут в активном использовании преимущественно на продакшн-сервере. Создание этих директорий в корне проекта, а не среди приложений, считается хорошим подходом и с точки зрения безопасности.

Текущая стркутура директорий:
.
└── django1
    ├── django1
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── media
    ├── requirements
    ├── static
    ├── manage.py
    └── README.rst

г) Внутри django1/ создаем папки для приложений (apps), для настроек (settings) и для шаблонов (templates). Концепция джанго предполагает использования как минимум нескольких приложений, поэтому гораздо нагляднее, когда они лежат в специальной папке, а не перемешаны с другими файлами и папками. Чтобы папка apps интерпретировалась как питоновский модуль, необходимо создать в ней пустой файл "__init__.py". Впоследствие в программе это даст возможность обращаться к приложениям через точку ("import django1.apps.app_name").

Текущая структура директорий:
.
└── django1
    ├── django1
    │   ├── apps
    │   │   └── __init__.py
    │   ├── settings
    │   ├── templates
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── media
    ├── requirements
    ├── static
    ├── manage.py
    └── README.rst

4. Создаем основное django-приложение

Как известно, любой django-проект состоит из одного или нескольких приложений. На текущий момент у нас создан пустой проект, подготовлена структура директорий, в рамках которой есть специальная папка для приложений (apps), но пока еще нет ни одного приложения. Пора бы это исправить — создадим основное приложение под названием "core":
    cd django1/django1/apps/
    django-admin.py startapp core

Текущая структура директорий:
.
└── django1
    ├── django1
    │   ├── apps
    │   │   ├── core
    │   │   │   ├── admin.py
    │   │   │   ├── __init__.py
    │   │   │   ├── models.py
    │   │   │   ├── tests.py
    │   │   │   └── views.py
    │   │   └── __init__.py
    │   ├── settings
    │   ├── templates
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── media
    ├── requirements
    ├── static
    ├── manage.py
    └── README.rst


Примечание: на данном этапе могут появиться скомпилированые файлы .pyc. Для наглядности они здесь не показаны.

5. Открываем проект в PyCharm

Здесь в целом и так все понятно: открываем PyCharm, жмем Open Directory и выбираем папку ~/projects_dev/django1. После открытия проекта нужно указать PyCharm, что обслуживать этот проект должно определенное виртуальное окружение, а не системное ПО, установленное глобально в систему. Для этого открываем File > Settings > Project Interpreter > Python Interpreters:

В этот список надо добавить интерпретатор Python из нашего виртуального окружения. Для этого жмем "+" и в появившемся окне выбираем файл "~/.virtualenvs/django1/python". PyCharm сам увидит, что это виртуальное окружение, подтянет список установленных в него пакетов и предложит ассоциировать это окружение с текущим открытым проектом:

Соглашаемся и жмем ОК. Таким образом, мы связали наш проект, открытый в PyCharm, с соответствующим виртуальным окружением. Теперь PyCharm готов к работе.

6. Задействуем систему контроля верий — Git

В репозитории Git будут храниться исходники нашего проекта, т.е. все содержимое корневой папки django1



Примечание: может возникнуть вопрос — если в репозитории хранятся только исходники, но не хранятся пакеты, установленные в соответствующем виртуальном окружении, то как понять, какие именно пакеты должны быть установлены на другом компьютере при переносе проекта? Для этого принято использовать команду "pip freeze", которая создает текстовый файл и прописывает в нем все приложения, установленные в виртуальном окружении проекта. При развертывании проекта на другой машине, по этому файлу можно воссоздать все необходимое программное обеспечение. Подробнее об этом будет описано ниже.



Для этого в среде PyCharm выделяем эту папку и инициализируем в ней репозиторий (меню "VCS > Enable Version Control Integration — Git" — это аналог консольной команды "git init").



После создания репозитория необходимо указать Git, с какими именно файлами ему следует работать, а какие следует игнорировать. Для этого создаем в корневой папке нашего проекта файл .gitignore со следующим содержимым (файл можно создавать прямо в PyCharm):
*.pyc
.idea/

local.py

В результате Git будет игнорировать все скомпилированные файлы Python, а также не будет индексировать скрытую папку .idea, автоматически содаваемую средой PyCharm при первом открытии проекта. По поводу игнорирования файла local.py, см. следующий пункт. Теперь добавим в индекс все остальные файлы проекта, набрав в консоли:
    git add .


Примечание: чтобы не переключаться между окнами, здесь и далее удобнее использовать терминал, встроенный прямо в PyCharm: меню "Tools > Open Terminal…"


Самое время сделать первый коммит — для этого достаточно нажать кнопку "Commit Changes" на панели инструментов PyCharm. Обратите внимание, что после коммита названия файлов в дереве слева изменят свой цвет — удобно. 

Итак, на локальной девелопмент-машине система контроля версий уже работает. Теперь нужно связать наш локальный репозиторий с удаленным Git-сервером (в моем случае — с репозиторием на BitBucket). Для этого заходим на сайт BitBucket, создаем там новый репозиторий и копируем его адрес. В моем примере это:
    "https://hexvolt@bitbucket.org/hexvolt/django1.git"

С помощью консоли подключаем к нашему локальному репозиторию созданный нами удаленный репозиторий под именем "origin":
    git remote add origin https://hexvolt@bitbucket.org/hexvolt/django1.git

После этого, для выгрузки всех изменений на сервер можно воспользоваться командой push (меню "VCS > Git > Push…"). Теперь весь наш проект хранится на BitBucket'е.

Примечание: в PyCharm довольно удобно работать c Git, что по сравнению с командной строкой неплохо экономит время. Например, при создании нового файла среда автоматически предлагает добавить его в индекс, основные операции можно выполнять одним нажатием кнопки, есть удобная визуализация веток репозитория, подсветка внесенных в файлы изменений и т.д. 

7. Наводим порядок с settings.py

У нас есть пустая (пока) папка settings/. Перенесем в нее файл настроек settings.py из корневой папки проекта и для удобства переименуем этот файл в defaults.py (поскольку эти настройки, по сути и являются настройками по умолчанию). Кроме того, на данном этапе целесообразно вынести настройки, относящиеся к девелопмент-версии нашего проекта, в отдельный файл local.py. В дальнейшем мы можем добавлять в папку settings/ другие файлы с теми или иными настройками.



Для того, чтобы django нашел наш модуль "django1.settings" после перемещения, необходимо сделать папку settings пакетом. Для этого внутри папки создаем файл "__init__.py" со следующим текстом:



from .defaults import *



try:

    from .local import *

except ImportError:

    pass



Таким образом, теперь django вместо модуля settings будет подключать пакет settings, который включает в себя все содержимое файла defaults.py, а также файла local.py в случае его наличия.



Примечание:
 для чего нужно вынесение локальных настроек в отдельный файл? Как известно, при развертывании проекта на продакшн-сервере, необходимо изменять настройки проекта (например, выключать режим отладки DEBUG = False). Если все настройки хранятся в одном файле, то при клонировании репозитория на продакшн-сервере этот файл появится в "боевой" версии проекта. Соответственно, чтобы на продакшене наш проект не работал с девелопмент-настройками, необходимо вручную заходить на сервер и править настройки на такие, которые будут пригодны именно для продакшн, а не для девелопмент-среды. Чтобы не повторять эти операции при каждом деплое, можно вынести локальные настройки в отдельный файл (local.py) и исключить его из индекса git (что мы и сделали в предыдущем шаге). Тогда в репозиторий (и на сервер) будет попадать все файлы настроек, кроме локальных, что избавит нас от необходимости ручной правки. Ну и наконец, чтобы продакшн-версия проекта не ругалась на отсутствие подключаемого файла, нужно внести заглушку "try… except" в файл __init__.py, что мы только что и сделали.




Итак, текущая структура директорий:

.

└── django1

    ├── django1

    │   ├── apps

    │   │   ├── core

    │   │   │   ├── admin.py

    │   │   │   ├── __init__.py

    │   │   │   ├── models.py

    │   │   │   ├── tests.py

    │   │   │   └── views.py

    │   │   └── __init__.py

    │   ├── settings

    │   │   ├── defaults.py

    │   │   ├── local.py

    │   │   └── __init__.py

    │   ├── templates

    │   ├── __init__.py

    │   ├── urls.py

    │   └── wsgi.py

    ├── media

    ├── requirements

    ├── static

    ├── manage.py

    └── README.rst


После всех манипуляций, желательно сделать очередной коммит, например, с комментарием "Settings moved" (не забываем предварительно добавить в индекс git файл defaults.py).


8. Настраиваем СУБД, подключаем South

Для работы с базами данных (что требуется практически всегда) необходимо:


  • установить в систему саму СУБД (для установки PostgreSQL — см. инструкцию);
  • настроить Django-проект на работу именно с этой СУБД (инструкция по подключению PostgreSQLздесь). 



Примечание: как известно, Django поддерживает разные СУБД (SQLite, MySQL, PostgreSQL и т.д.). Если мы будем работать с SQLite — то ничего устанавливать и настраивать на данном этапе не нужно, т.к. по умолчанию проект уже настроен на SQLite.



Что такое SouthSouth — это приложение для Django-проектов, которое является альтернативой утилите syncdb. Избавляет от головной боли при внесении изменений в структуру моделей БД. Как известно, штатная утилита syncdb может только создавать таблицы по моделям, но не может изменять их при изменении структуры моделей. Поэтому, когда мы правим код моделей (что в процессе разработки бывает довольно часто), приходится вручную изменять таблицы БД или пересоздавать всю базу. South может автоматически отслеживать изменения программного кода и соответствующим образом обновлять БД.


Активировав виртуальное окружение нашего проекта (командой "workon django1"), устанавливаем South:
    pip install south

Примечание: пакеты и приложения можно также устанавливать прямо из среды PyCharm в разделе File > Setting > Python Interpreters

Дописываем South в список установленных приложений INSTALLED_APPS нашего проекта (файл default.py в settings):

INSTALLED_APPS = (
    …
    'django.contrib.admin',
    'django1.apps.core',
    'south',
)

Для инициализации установленного приложения необходимо один раз запустить утилиту syncdb:

    python manage.py syncdb



Примечание: эту команду нужно запускать, находясь в виртуальном окружении нашего проекта. Альтернативный способ — в среде PyCharm выбрать меню "Tools > Run manage.py Task…". Поскольку syncdb в нашем проекте запускается впервые, система захочет  создать суперпользователя и запросит его имя, e-mail и пароль.


После этого в БД автоматически создадутся таблицы, необходимые для работы South, и manage.py станет поддерживать несколько новых команд, которые мы будем использовать в дальнейшем при работе с базами. На этом базовая настройка БД завершена, поэтому можно сделать коммит в наш репозиторий.



Как пользоваться South? Как правило, последовательно вызываются всего две команды:

  • schemamigration — анализирует изменения, внесенные в код моделей, и создает соответствующий файл миграций, который позволит отразить их в БД. Первый раз запускается с ключом —initial, все последующие разы — с ключом —auto;
  • migrate — считывает предварительно созданный файл миграций и согласно ему вносит измененя непосредственно в БД.

Применительно к нашу проекту, пока мы еще не создавали модели в приложении core, выполняем:

    python manage.py schemamigration core —initial

и применяем все изменения (даже если их пока и нет):

    python manage.py migrate core



В дальнейшем, внося изменения в код моделей в приложении core, мы будем применять их следующим образом:

    python manage.py schemamigration core —auto

    python manage.py migrate core



Примчение: указанные команды набираются в терминале под виртуальным окружением проекта django1



Принцип работы и порядок работы South хорошо описан тут.


9. Стратегия дальнешей разработки

Дальше — непосредственно разработка django-проекта. При этом я обычно веду две git-ветки — master и develop, которые существуют постоянно. В master ветку выкладываются только полностью рабочие версии проекта, а в develop — промежуточные версии. Т.е. весь процесс написания и отладки кода ведется только в ветке develop. Когда же какой-то новый функционал сайта полностью отлажен — в мастер-ветку подтягивается последний коммит из ветки develop. При таком объединении важно не использовать режим fast-forward, поэтому команда объединения должна быть с таким ключом:



    git merge -m "some_text" —no-ff develop



В противном случае после операции merge коммиты с двух веток сольются в одну.



Таким образом, в master-ветке гарантированно будут только рабочие версии проекта, именно они и будут выкладываться на сервер. В процессе разработки необходимо не забывать почаще делать коммиты и выкладывать изменения в удаленный репозиторий на сервере.



О том, как разрвернуть проект из репозитория на продакшн-сервере, будет описано чуть позже.


 
 

8 комментариев:

  1. Спасибо! Мне, как новичку, прояснили и помогли организовать воркфлоу.

    Ответить

     
     
  2. >>О том, как разрвернуть проект из репозитория на продакшн-сервере, будет описано чуть позже.

    Статья планируется?)

    Ответить

     
     
  3. Хорошая статья, спасибо. Очень хочу статью про развёртывание и обновление проекта, после изменение в ветке мастер.

    Ответить

     
     
  4. полгода прошло, где продолжение? )

    Ответить

     Ответы

     
      • Спасибо за интерес! Работаю веб-девелопером, к сожалению пока нет времени на написание

         
         
     
     
  5. Отличная статья. Главное, наглядная.

    Внутреннее противоречие вызывает один момент: судя по тому, как себя ведёт Django, расположение приложений в папке apps противоречит внутренней логике. По официальному ману приложения создаются через manage.py в той же папке, что и сам manage.

    Ответить

     Ответы

     
      • в принципе дело вкуса. Сейчас я работаю на одном проекте — там все аппы свалены в корневую папку. Проект довольно большой и количество приложений там — 25+. В итоге имеем "колбасу" из папок в корне проекта с маленьким скролликом, которая перемешана с кучей другий папок (settings, static, templates, …) — довольно напряжно это все постоянно листать и отыскивать где там приложение, а где не приложение

         
         
     
     
  6. Большое спасибо за статью, очень полезная информация в сжатом и понятном виде. С течением времени и обновления Django до версии 1.7 в south нет необходимости, при его применении выдаеться исключение. Теперь его функции интегрированны в сам django, а всё остальное очень актуально. Еще раз большое спасибо и жду следующих публикаций

    Ответить

     
     

 

 

Поиск

  
 
 
 

Ярлыки

Обо мне

hexvolt
Изучение Linux, веб-программирование

Просмотреть профиль

 
 
 

Полезные страницы

Читатели

 
 
 

Подпишитесь на hexvolt-блог

Сообщения
 

Комментарии
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Шаблон "Picture Window". Технологии Blogger.
 
 
 
 
 
 
 
 
 

http://hexvolt.blogspot.ru/2014/05/django-workflow.html

Губарь Маргарита Александровна