В разработке своих проектов на Django я придерживаюсь архитектуры, близкой к той, которую описал Мальколм Трединник в своей статье "Django Tip: Developing Without Projects". Странно звучит, да, разработка проектов используя методику разработки без проектов.
Но это только на первый взгляд. В действительности я не использую терминологию Django, в которой проект - это продукт действия django-admin.py startproject
, порождающий дополнительную ветвь в иерархии и приводящий к повсеместному использованию projectname. в питон коде. Для меня проект - это скорее объединение приложений, как reusable (как-то django-tagging, django-mptt и многие многие другие) с одной стороны, так и тех, которые разрабатываются исключительно для текущего веб-сайта, под одной общей крышей (settings.py, urls.py).
В идеале архитектура любого моего проекта выглядит как:
project/ application/ another_application/ locale/ templates/ settings.py urls.pyТ.е. по-большому счету ничего лишнего. Управление и деплоймент проекта ведется при помощи универсальной утилиты django-admin.py, которой передаются переменные DJANGO_SETTINGS_MODULE (settings) и PYTHONPATH (абсолютный путь к project/) (опять же в идеале создаются алиасы для каждого из проекта вида django-project и это в дальнейшем облегчает их использование в коммандной строке).
И казалось бы жизнь прекрасна и чудесна. Но так было до сегодняшнего дня, а сегодня я решил установить django-compress - приложение для сжатие CSS и JavaScript файлов. И одним из условий его использования было выполнение комманды
$ ./manage.py synccompressЯ, конечно, ничуть не смутился и попытался было:
$ django-project synccompressно эта попытка закончилась
Unknown command: 'synccompress' Type 'django-admin.py help' for usage.
Причина оказалось простой и, наверное, вполне логичной. django-admin.py вызывает django.core.management.execute_from_command_line, manage.py же, лежащий в директории проекта, после его создания (startproject), вызывает django.core.management.execute_manager. Вся же разница состоит в том, какая утилита управления (ManagementUtility) инициализируется и выполняется в этих функциях. И в итоге, ProjectManagementUtility считывает дополнительные команды, которые находятся в директории commands
всех приложений, перечисленных в INSTALLED_APPS проекта. Именно это и дает возможность выполнения кастомных команд.
Собственно все это и навело на мысль создания "магичной" (новый тренд в джанго-среде) утилиты django-manage.py. Программный код этого велосипеда:
#!/usr/bin/env python import os, sys if __name__ == '__main__': try: dirname = os.environ['PWD'] except KeyError: import subprocess dirname = subprocess.Popen('cd', shell=True, stdout=subprocess.PIPE).communicate()[0].strip() sys.path.append(dirname) try: settings = 'settings' try: __import__(settings) except ImportError, e: settings = os.path.basename(dirname) + '.settings' __import__(settings) except ImportError, e: sys.stderr.write("Error: Can't find the file 'settings.py' in the current work directory %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % dirname) sys.exit(1) os.environ['DJANGO_SETTINGS_MODULE'] = settings from django.core import management utility = management.ProjectManagementUtility(None, os.path.basename(dirname)) utility.execute()Установка выполняется копированием сохраненного кода в PATH и выдачей ему прав на исполнение (последнее только для Unix'ов).
Примеры использования тоже вполне очевидны:
$ cd /path/to/project $ django-manage.py help django-manage.py[options] [args] Django command line tool, version 0.97-pre-SVN-unknown Type 'django-manage.py help ' for help on a specific subcommand. Available subcommands: adminindex createcachetable dbshell diffsettings dumpdata flush inspectdb loaddata reset runfcgi runserver shell sql sqlall sqlclear sqlcustom sqlflush sqlindexes sqlinitialdata sqlreset sqlsequencereset startapp synccompress syncdb test testserver validate
Ну и подитоживая могу лишь порадоваться, что процесс расширения Django под свои нужды проходит так просто и безболезненно.
Важно! Сей метод подходит лишь для архитектуры, описанной мной в начале поста, если вы используете архитектуру Django-проектов используйте для этих же целей manage.py, расположенный в корне директории проекта.
UPD 1 Добавлена проверка текущей рабочей директории для Windows, так как в нем нет ключа PWD в словаре os.environ.
UPD 2 Добавлена поддержка settings, project.settings (стандартной архитектуры проектов Django).
0 комментариев:
Отправить комментарий