Начало работы с проектом на Django 1.6

  • 3 года назад

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

К концу этой статьи у вас будет:

  • Полностью функциональный проект Django 1.6
  • Все ресурсы в проекте находятся в системе контроля версий (git или Mercurial)
  • Автоматическое возвращение в прежнее состояние и модульное тестирование (используя библиотеку unittest)
  • Среда независимой установки вашего проекта (используя virtualenv)
  • Автоматическое развертывание и тестирование (с помощью Fabric)
  • Автоматические миграции базы данных (с помощью South)
  • Разработка рабочего процесса, который маcштабируется в соответствии с вашим сайтом.

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

Перед началом работы.

Предполагается практическое знание Python. Так же некоторый опыт работы с Django может быть очень полезен, но не является строго необходимым. Вам понадобится git или Mercurial для управления версиями. Это все!

Подготовка к установке.

Я предполагаю, что у вас уже есть установленный Python. Если у вас нет установленного Python, то перейдите на python.org и найдите инструкции по установке для вашей операционной системы. Я запустил установку 64-bit Arch Server от Linode, чем я очень доволен.

Так в чем же заключается первый шаг? В установке Django, правильно? Не совсем так. Одна общая проблема с установкой пакетов непосредственно на вашу текущую область на сайте заключается в том, что если у вас имеется более одного проекта или Python используется еще для чего-нибудь, кроме Django , то вы можете столкнуться с проблемой совместимости между вашими приложениями и установленными пакетами. По этой причине, мы будем использовать virtualenv и превосходное расширение virtualenvwrapper, чтобы управлять установкой нашего Django.

Это является общей рекомендованной процедурой среди всех пользователей Python и Django. Если вы используете pip для установки пакетов (и я не вижу причин, почему вы не должны его использовать), то вы можете получить virtualenv и virtualenvwrapper, просто установив последний.

pip install virtualenvwrapper

После того, как пакеты установилось, добавьте следующие строки в ваш файл запуска оболочки (.zshrc, .bashrc, .profile, etc).

export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

Перезагрузите ваш файл запуска оболочки (например source .zshrc).

Создание новой среды.

Создать виртуальную среду очень просто. Просто введите:

mkvirtualenv django_project

где django_project - это то имя, которое вы дали вашему проекту.

Вы заметите, что сразу произойдет несколько вещей:

  • В начало пути в вашей оболочки добавилось (django_project)
  • Setuptools и pip были автоматически установлены (в виртуальную оболочку)

Это чрезвычайно полезная часть virtualenvwrapper: он автоматически готовит вашу среду таким образом, что позволяет сразу приступить к установке пакетов при помощи pip. Часть django_project напоминает, что вы используете virtualenv вместо установленного в вашей системе Python. Чтобы выйти из виртуальной среды, просто введите deactivate. Когда вы захотите возобновить работу над вашим проектом, просто введите workon django_project. Обратите внимание, что в отличие от обычного virtualenv, не имеет значения в каком месте вы вводите эти команды .

Установка Django

«Подождите, установка Django? Я уже установил Django!». Фантастика. Вы не собираетесь его использовать. Вместо этого мы будем использовать virtualenv, которая не будет создавать беспорядок пакетов в системе, т.к. все пакеты необходимые проекту будут установлены в виртуальное окружение проекта). Чтобы установить Django в virtualenv, просто введите:

~~~{.bash} pip install django


У вас должна будет загрузится последняя версия Django, которая будет установлена в оболочку **virtualenv**. Вы можете подтвердить это следующими действиями:

~~~{.sh}
which django-admin.py

Должен отобразится путь, который должен указывать на ваш каталог $HOME/.virtualenvs/. Если не указывает, то включить virtualenv можно выполнив команду workon django_project.

Создание django проекта

Прежде чем мы непосредственно начнем работу с проектом, мы должны немного поговорить. Я консультировался по ряду проектов Django/Python и говорил с многочисленными разработчиками в последние несколько лет. В подавляющем большинстве случаев, имеют много проблем и сложностей те, кто не пользуется какой-нибудь системой контроля версий. Это может показаться невероятным (учитывая популярность GitHub), но некоторые разработчики просто никогда не работали с системой контроля версий. Другие считают, что, поскольку, «Это небольшой проект», то в этом нет необходимости. ОШИБАЮТСЯ.

НИ ОДИН ИЗ ИНСТРУМЕНТОВ, ПЕРЕЧИСЛЕННЫХ ЗДЕСЬ, НЕ БУДЕТ БОЛЕЕ ПОЛЕЗНЫМ, ЧЕМ ИСПОЛЬЗОВАНИЕ СИСТЕМЫ КОНТРОЛЯ ВЕРСИЙ.

Раньше я только упоминал о git (D)VCS. Однако этот проект, будучи на Python, может использовать Mercurial, которая является достойной альтернативой, базирующейся на Python. Обе VCS достаточно популярны, и учебные материалы можно легко найти в Интернете. Убедитесь, что у вас установлен git или Mercurial. Обе наверняка доступны через ваш дистрибутив и систему пакетов операционной системы.

Если вы планируете использовать git, GitHub является очевидным выбором для хранения удаленного хранилища. При работе с Mercurial, Bitbucket отличный выбор (он также поддерживает git, так что вы можете использовать его в любом случае).

(Начало) Управление своей средой

Пока мы еще ничего не сделали, но знаем, что мы хотим, чтобы все было под контролем. У нас есть несколько дел, которые мы собираемся сделать: сам наш код (включая шаблоны и т.д.) и вспомогательные файлы, такие как фикстуры базы данных, South миграции (подробнее об этом позже), и requirements.txt файл, в котором перечислены все пакеты для вашего проекта и которые будут автоматически установлены с их зависимостями (избавляет нас от того, чтобы вручную устанавливать пакеты).

Давайте двинемся дальше и создадим каталог проекта. Используйте команду startproject из django-admin.py, чтобы его создать.

django-admin.py startproject django_project

Мы увидим простой каталог: django_project. Войдя в каталог django_project, мы увидим другой каталог django_project, в котором содержатся: settings.py, urls.py, и wsgi.py. На том же уровне, что и второй каталог django_project, есть файл manage.py.

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

Вы можете быть удивлены, почему еще в Django 1.4 команда startproject была добавлена вместе с уже существующей командой startapp. Ответ заключается в разнице между Django "projects" и Django "apps". Вкратце, проект - это весь веб-сайт или приложение. «App» представляет собой маленькое, (надеюсь) автономное приложение Django, которое может быть использовано в любом проекте Django. Если вы делаете приложение для блогов, названое "SuperBlogger", значит "SuperBlogger" ваш проект Django. Если "SuperBlogger" поддерживает опросы читателей, то «опросы» было бы приложением Django используемое в "SuperBlogger". Идея заключается в том, что ваше приложение «опросы» должно использоваться в любом проекте Django, в котором нужны опросы, не только в "SuperBlogger". Проект представляет собой совокупность различных приложений наряду с самим проектом. Приложения могут быть использованы в нескольких проектах.

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

Настройка нашего репозитория

Поскольку в нашем проекте уже имеются некоторые файлы (конечно, всего лишь пара-тройка «сырых скриптов» и пустых файлов конфигурации), сейчас самое подходящее время инициализировать наш проект в систему управления версиями. Вот, как это сделать в git и Mercurial.

git:

git init

Это создаст хранилище git в текущем каталоге. Затем поместите все файлы в git хранилище.

~~~{.sh} git add .


Теперь мы закоммитим их:

~~~{.sh}
git commit -m 'Initial commit of django_project'

Mercurial:

~~~{.sh} hg init


Это создаст хранилище Mercurial в текущем каталоге.

~~~{.sh}
hg add django_project

Теперь мы добавим их в наш новый репозиторий:

~~~{.sh} hg commit -m 'Initial commit of django_project'


Если вы планируете пользоваться такими сервисами, как GitHub или Bitbucket, то сейчас самое время сделать `push`.

## Использование South для миграции базы данных.

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

### Когда начинаете пользоваться South

В прошлых статьях я рекомендовал с самого начала вашего проекта использовать South. Для относительно простых проектов, это прекрасно. Но если,  у вас есть много моделей, которые меняются также быстро, как ваш прототип, тогда еще не время использовать South. Тогда просто удалите и заново создайте базу данных, когда это необходимо. Вы можете прописывать скрипты, чтобы заполнять базу данных с некоторыми тестовыми данными и редактировать их, если возникнет необходимость. Однако, после того, как ваши модели перестанут меняться, нужно прибегнуть к помощи South так скоро, насколько это только возможно. Это можно сделать так: `./manage.py convert_to_south <app_name>`.

### Установка и настройка

Так же на нашем virtualenv устанавливаем South следующим образом:

~~~bash
pip install south

Мы настраиваем наш South добавив его в INSTALLED_APPS в файле settings.py. Добавим, что сейчас также нужно настроить базу данных для проекта, затем запустить python manage.py syncdb. Вам будет предложено ввести имя суперпользователя и пароль. Что еще более важно, нужно, что бы South установил базу данных с таблицами.

Вы могли заметить, что мы только что запустили syncdb без добавления приложения в проект (без добавления в INSTALLED_APPS). Мы делаем это для того, чтобы в начале был установлен South. Все миграции в наших собственных приложениях должны будут осуществляться при помощи South, в том числе, первоначальные миграции.

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

Чтобы сохранить или «зафиксировать» проект на той или иной стадии, давайте посмотрим, что было изменено.

git

~~~{.sh} $ git status

On branch master

Changes not staged for commit:

(use "git add ..." to update what will be committed)

(use "git checkout -- ..." to discard changes in working directory)

#

modified: django_project/settings.py

#

Untracked files:

(use "git add ..." to include in what will be committed)

#

django_project/.settings.py.swp

django_project/init.pyc

django_project/settings.pyc


**Mercurial**

~~~{.sh}
$ hg status

M django_project/django_project/settings.py
? django_project/django_project/.settings.py.swp
? django_project/django_project/__init__.pyc
? django_project/django_project/settings.pyc

Как в git, так и в Mercurial, вы можете заметить, что есть файлы, которые вы никогда не хотели фиксировать, python файлы, такие как .pyc и vim файлы swap .swp выше. Чтобы игнорировать эти файлы, создайте файл .gitignore или .hgignore в каталоге вашего основного проекта и добавьте шаблон оболочки, чтобы отразить в ней файлы, которые вы не хотите сохранять.

Например, содержимое этого файла может быть:

~~~{.sh} .pyc .swp


Перед тем, как это все сделать, у наc есть еще одно место для записи: наши установленные пакеты Python. Мы хотим следить за пакетами Python, которые мы используем в проекте и, что бы мы могли легко воссоздавать нашу среду на продуктовом сервере. К счастью, в `pip` есть команда, которая делает то, что нам нужно.

~~~bash
pip freeze > requirements.txt

Я направил вывод в файл, названный requirements.txt, который мы добавим в систему управления версиями, поэтому у нас всегда есть обновленный список того, что используется в пакетах.

(git/hg) add django_project/settings.py requirements.txt
(git/hg) commit -m 'Added South for database migrations'

Настройки нового стиля

Одним из основных паттернов для файла settings.py, является его перемещение в другой каталог, например conf или config. Но в этом случае вам придется сделать небольшое изменение в manage.py, чтобы согласовать перемещение.

С settings.py и INSTALLED_APPS можно быстро ввязнуть в трясину сторонних пакетов в общих приложениях Django и в ваших собственных приложениях. Я бы хотел разделить INSTALLED_APPS на три категории:

  • DEFAULT_APPS: приложения Django framework
  • THIRD_PARTY_APPS: например, South
  • LOCAL_APPS: приложения, которые вы создаете

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

Просто помните, в конце концов, есть строка, подобная следующей:

~~~{.python} INSTALLED_APPS = DEFAULT_APPS + LOCAL_APPS + THIRD_PARTY_APPS


В противном случае, Django будет жаловаться, что нет определений INSTALLED_APPS.

## Создание нашего приложения

Используйте manage.py, чтобы создать приложение обычным способом (python manage.py startapp myapp) и добавьте его в INSTALLED_APPS. Кроме того сделайте manage.py выполняемым (`chmod +x manage.py`), так вы можете просто ввести ./manage.py <command>. Честно говоря, очень мало разработчиков это делают. И я всю жизнь не могу понять, почему.

Первое, что мы сделаем перед тем, как добавим модели, скажем South, что мы хотим управлять изменениями в наших моделях при помощи миграций:

~~~bash
python manage.py schemamigration myapp --initial

Эта команда создаст файл миграций, который можно использовать для того, чтобы вносить изменения в наши модели (если они у нас будут) и в базу данных, без необходимости полностью удалять и восстанавливать её. Это также позволит нам отменить изменения, если они обернутся боком для нас. Мы будем использовать файлы миграций для переноса изменений в базе данных (даже если их нет), используя:

python manage.py migrate myapp

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

python manage.py schemamigration myapp --auto

Это будет проверять модели в myapp и автоматически добавлять, удалять, или изменять таблицы в базе данных. Изменения могут быть применены к базе данных при помощи команды migrate, как описано выше.

Наша область разработки

Нужно развить хорошую привычку писать и тестировать код отдельно от ваших рабочих файлов, это нужно, например, для того, чтобы не привести в нерабочее состояние ваш сайт от ошибки кодирования при добавлении новой функциональности. В git и Mercurial это сделать очень просто. Просто создайте каталог где-нибудь в другом месте, не там, где установлен django_project. Можете создать новое виртуальное окружение для среды разработки dev со своим собственным каталогом, в этом окружении можете эскперементировать и разрабатывать (используя ветку dev). А текущий django_project использовать в качестве эмулятора продуктового сервера (используя ветку master) и выкатывать туда обновления, перед отправкой на реальный продуктовый сервер.

В новый каталог разработки (dev) скопируйте ваш текущий проект при помощи git или Mercurial:

~~~{.sh} (git/hg) clone /path/to/my/project/


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

Вот, как сделать это для каждого инструмента:

**git**

~~~{.sh}
git checkout -b <branchname>

Который так же будет создавать новую ветку и проверять ее. Почти все ваши области разработки (dev, prod) должны работать с ветками, например, ветка master имитирует «продуктовую версию сайта» ( или «или текущую версию сайта»), master так же может быть использован для восстановления в любое время.

(Mercurial)

hg branch <branchname>

Использование Fabric для развертывания

Так, у нас есть все, что необходимо для приложения на Django. Что теперь мы будем делать? Fabric. Fabric можно использовать для различных целей, но он реально необходим при развёртывании.

~~~{.sh} pip install fabric


Fabric ожидает файл, с названием **fabfile.py**, который определяет все действия, которые мы можем предпринять. Давайте сейчас его создадим. Разместите fabfile.py в корневом каталоге вашего проекта.

~~~{.python}
from fabric.api import local

def prepare_deployment(branch_name):
    local('python manage.py test django_project')
    local('git add -p && git commit') # or local('hg add && hg commit')

Это поможет запустить тесты и зафиксировать изменения, но только, если ваши тесты проходят. На данный момент просто сделайте «pull» на вашем продуктовом сервере и код начнет развертываться. Давайте добавим ещё что-нибудь для актуального развёртывания. Добавьте это к вашему fabfile.py:

~~~{.python} from fabric.api import lcd, local

def deploy(): with lcd('/path/to/my/prod/area/'):

    # git...
    local('git pull /my/path/to/dev/area/')

    # Mercurial...
    local('hg pull /my/path/to/dev/area/')
    local('hg update')

    local('python manage.py migrate myapp')
    local('python manage.py test myapp')
    local('/my/command/to/restart/webserver')

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

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

Теперь у нас есть наш созданный fabfile.py, как же мы его применим? Очень просто. Просто запустите:

~~~{.sh}
fab prepare_deployment
fab deploy

Настройка модульных тестов

Если вы что-нибудь обо мне знаете, то наверняка, это будет то, что я обожаю автоматические тесты. Слишком много Django проектов создаются без каких-либо тестов. Это еще одна из тех вещей, на которую стоит потратить немного времени, но она с лихвой окупится в будущем. Если вы когда-нибудь отлаживали приложения, используя оператор print, то наличие корректных тестов для этого места могло бы вам освободить уйму времени. Для Django, python модуля unittest вполне достаточно. Ниже приведен маленький пример тестирования на одном приложении:

~~~{.python} import datetime

from django.test import TestCase from myapp.models import Post

class BlogPostTestCase(TestCase): def setUp(self): Post.objects.create(id=1, title='Starting a Django 1.6 Project the Right Way', date=datetime.datetime.now(), category='Django') Post.objects.create(id=2, title='Python\'s Hardest Problem', date=datetime.datetime.now(), category='Python')

def test_posts_have_category(self):
    """Animals that can speak are correctly identified"""
    first_post = Post.objects.get(id=1)
    second_post = Post.objects.get(id=2)
    self.assertEqual(first_post.category, 'Django')
    self.assertEqual(second_post.category, 'Python')


Вы можете поместить этот код в файле с именем `test_<appname>.py` и разместить там же где и каталог приложения, который нужно протестировать. Чтобы запустить тесты, просто введите `./manage.py test <appname>`. Fabfile, который мы создали уже знает как запускать тесты перед развертыванием, поэтому нет необходимости делать еще какие-нибудь изменения.

Наслаждайтесь новым приложением Django

Вот и все! Вы готовы начать свою реальную разработку. Сейчас начинается самое интересное. Просто помните: коммитить часто, тестировать все, и не нужно писать код, который вы не сможете протестировать.

Комментарии

0