15 марта 2012 г.

Новинки Django 1.4, day 5: Структура проекта


На сегодня у нас изменения в структуре django-проектов. Они достаточно важные, поэтому рассмотрим их по-подробней.

Изменения в manage.py и структуре проектов
Docs
Discussion on django-developers

Зачем

Рассмотрим детально проблему, которую решают разработчики django в новом релизе, изменяя структуру проекта. Вот как выглядел базовый каркас, который генерила команда startproject до версии 1.4:
mysite/
    __init__.py
    manage.py
    settings.py
    urls.py
    myapp/
        __init__.py
        models.py
Недостатком данной структуры является наличие в пакете mysite исполняемого консольного скрипта manage.py, который по сути не связан с проектом и является «точкой входа». При запуске manage.py из консоли, папка mysite оказывается в sys.path и мы можем получить доступ к урлам и настройкам через import urls и import settings соответственно. Тем не менее, Django по-умолчанию предлагает импортировать урлы и настройки с указанием названия пакета (ROOT_URLCONF='mysite.urls'), вероятно, для того, чтобы не засорять пространство имён верхнего уровня. Дабы сделать подобный импорт возможным, функция setup_environ колдует с sys.path, добавляя родительскую по отношению к mysite папку, а потом возвращает sys.path в предыдущее состояние.

Не говоря о том, что это совсем непитонический путь, данных подход создавал целый ряд проблем, связанных с деплойментом, дистрибуцией приложений и т.д. Например, при добавлении родительской папки в sys.path, могли импортироваться лежащие рядом пакеты, создавая трудноотcлеживаемые проблемы.

Решение

В целях борьбы с подобной магией было предложено решение по выделению manage.py из папки проекта на уровень выше в файловой иерархии:
manage.py
mysite/
    __init__.py
    settings.py
    urls.py
    myapp/
        __init__.py
        models.py

Во-первых, эта структура должна сподвигнуть авторов новых проектов и мигрирующих старые следовать единой системе импортов. Например, ранее можно было импортировать в разных местах приложение как import myapp, так и import myproject.myapp. Теперь же все импорты пакетов, находящихся внутри mysite, должны будут однозначно включать название родительского модуля.

Во-вторых, изменение структуры позволило упростить код скрипта manage.py:
#!/usr/bin/env python
import os, sys

if __name__ == "__main__":
  os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")

  from django.core.management import execute_from_command_line

  execute_from_command_line(sys.argv)

Начиная с 1.5 старый manage.py станет выдавать Deprecation warning, а в 1.6 перестанет работать совсем. Будьте аккураты при обновлении структуры проекта, если вы импортируете пакеты не единообразно, могут возникнуть проблемы с новым manage.py (т.к. раньше он маскировал эти ошибки).

Это ещё не всё

Продолжение о шаблонах проекта и приложений читайте завтра на этих выходных.

Комментариев нет:

Отправить комментарий