Расположение файлов в проектах Django
Последнее время мне всё более и более странным (я бы даже сказал “недальновидным”) кажется решение авторов оригинального
туториала по Джанге показывать именно такой формат расположения файлов в джанге (и уж тем более то, какой
sys.path они там используют): в туториале все файлики, созданные с помощью startproject, лежат в одной директории
вместе с приложениями. Соответственно, все импорты выглядят как from someproject.someapp import views.
Мне понятно, откуда ноги растут — на деле у них все приложения лежат в sys.path, и потому импортируют они оттуда как
from someapp import views, а проект — это лишь настройки да корневой конфиг урлов. Тогда можно родительскую для всех
проектов директорию положить в sys.path, и менять только DJANGO_SETTINGS_MODULE. Но в любом случае одним
интерпретатором питона для двух джанговских проектов не обойдёшься (спасибо этому самому DJANGO_SETTINGS_MODULE), а
способность к лёгкому созданию дистрибутива и его распространению страдает порядочно (что особенно важно для
опенсорсовых проектов).
Поэтому мне значительно больше нравится другой подход к делу, который я применяю во всех своих проектах, в том числе и в Byteflow:
project/
apps/ # собственно приложения
template/ # шаблоны
static/ # статические файлы — картинки оформления, стили, JS
media/ # файлики, загруженные пользователями, не версионируется
locale/ # переводы
compat/ # тут библиотеки типа django-atom
manage.py # файлы, относящиеся к описанию проекта
settings.py
urls.py
...
При этом в sys.path добавляется сама директория проекта, DJANGO_SETTINGS_MODULE становится равен settings, а в
settings.py двумя строками кода в sys.path добавляется и apps/ с compat/1. В результате все импорты простые и не
содержат имени проекта (что тупо хотя бы потому, что я не могу склонировать проект рядом и поэкспериментировать в нём
из-за того, что будут проблемы с импортами), а проект становится достаточно независимой вещью, которая для
разворачивания на каком-то сервере требует только Джангу и библиотеки, которые достаточно распространённые и/или
большие для того, чтобы не включать их в проект.
Как это делается, можно увидеть в settings.py у Byteflow.
Comments
Здравствуй рельсы и пилоны :-)
А еще бы джангу прямо в проект фризить, нужной версии прямо из репозитория, и плагины внешние. Полный контриб всегда на месте. А еще… ой ладно, хватит :-)
Нууу… В майдеко-то было точно так же. А что конкретно в лейауте не нравится-то?
Прикольно, у нас похожий лайаут, только весь код в src, и locales не вынесены на верх. Зато в каждом проекте своя зафризиная версия джанги ;)
Я стараюсь держать все проекты на последней версии транка, ну и плюс меркуриал не умеет (прямо) такого, как
svn:externals.Кстати, а git вроде умеет, но я пока только читал, сам не пробовал. Говорят, git-remote помогает. Но это, разумеется только в том случае, если все репозитории на git, что маловероятно.
Ну, с меркуриалом тоже можно такое учудить, используя forest, но опять же, если все репозитории — меркуриал. Плюс для меня совсем не очевидно, зачем это надо. :)
У нас всё в лоб. Просто в меркуриале лежит svn. Заходишь туда, и: svn up, hg addremove, hg ci -m “Django update”
Хех, хардкор. :) Не, я всё-таки предпочитаю джангу как-то отдельно апдейтить, уж очень она большая…
Потыкавшись в грабли с тем что при обновлении одного проекта слетает другой, которым заниматься времени нет, пришёл к выводу забить на все возможные минусы данного подхода. Кстати минусов особо и не замечено.
А, не. Есть один. hg churn показывает что 95% изменений всего проекта я накоммитил ;)
Потому что надо апдейтить django в отдельной рабочей копии и из под другого пользователя. Какого-нибудь svn-updater.
Ну с автором решить просто —
hg ci -u svn-updater, и дело в шляпе. ;)А на тему слетания… Ну да, но меня пока это не преследует, а там и релиз не за горами. :) Но твои проблемы я хорошо понимаю, просто у меня количество проектов небольшое.
Да понятно, но это же и не проблема вовсе. Я churn этот раза три в жизни запускал. Вспомнилось просто.
Кстати да.
Мы правда джангу в отдельном бранче держим (базаровцы.. хотя у вас тоже самое можно делать =)). Соответственно цикл примерно такой:
/trunk /django
апдейтим джангу
коммит
экспорт
мержим то что только что сэкспортнули
Все такие пляски с бубнами, потому что бранч джанги:
А так.. коммиты в транке простенькие, можно откатится куда угодно, и тысячи .svn/ не мешаются в транке.
В принципе нормальный такой лэйаут.. Только как ты static media делишь то? Или я туплю или ты дэвид блэйн.. MEDIA_ROOT ведь вроде один и все линки с get_something_url аппендятся к нему.. Как ты смог разделить их?
Посмотреть в код тебе религия помешала? ;)
MEDIA_ROOTиMEDIA_URLтак и направлены вmedia/, чтоб джанговские хендлеры не ломались, а дляstatic/я специально завёлSTATIC_ROOTиSTATIC_URL, которые контекстным процессором отправляются в темплейты.Я конечно гляну что там у тебя в коде.. но думаю про это тебе пост надо написать, всё-таки проблема с которой сталкиваются все, а решение спрятано как ты говоришь аж в конекстном процессоре..
Ну, я написал, как я сделал. Кому будет интересно — прочтёт комментарий, не так много инфы, чтобы в отдельный пост это писать.
Эх, надо будет у себя все переколбасить. Но это после отпуска. Сейчас уже ни о чем не хочется думать :)
Кстати, когда уже для django будет нормальный инсталятор? Я имею ввиду такой, чтобы, скажем, имея на сервере django определенной версии в python пути, достаточно было распаковать где-то исходники движка, открыть определенный URL и настроить все через веб.
Мечты-мечты… :D Да, деплой было бы неплохо как-то заапгрейдить, а то сейчас это всё может быть достаточно муторно. :)
Хм.. дефолтовый джанговский лэйаут явно для не очень крупных проектов придуман. А тем кому надо — сами и меняют.
Вообще ваш подход сразу противоречит большинству других. То есть если взять byteflow и поставить его грамотно system-wide, то будет небольшая попа в виде “черт возьми, всё в pythonpath?!”. Темплейты — пофик, их хоть через pkg_resources грамотно вытаскивать можно. Но вот статику.. =)
Вот мой вариант. Соответственно, в pythonpath у нас самое естественное — pylib (при system-wide установке — станет site-packages).
Но это — минижопа для сторонних приложений. Во-первых, многие:
Ну и ещё так, по мелочи… Но это всё чинится на раз-два =).
p.s. я специально пытался не колдовать с sys.path p.p.s. а проблема импорта с именем… ээээ… from .. import ? p.p.p.s а проблема “склонировать”… мм. Поменять 1 PYTHONPATH в консоли — и будет клон. Или я не понял в чем проблема?
Ога, я об этом как-то не задумывался, потому что sys.path для всех джанговских проектов своих всегда дорисовываю в VirtualHost’ах у апача. Надо будет поразмышлять…
В том, что люди показывают свои приложения, где имя самой верхней директории — важно в коде питона. А это не очень клёво. :)
Вообще было бы неплохо придумать какой-то универсальный лейаут, который бы все использовали. У тебя он слегонца развесистый выходит, на самом-то деле. :)
Ещё один момент — не люблю файлы темплейтов рядом с питоновскими, правда сейчас задумался — как-то это иррационально, ведь поиск по файлам можно ограничивать типом файла… Но пока всё ещё не люблю. :)
ура! я думал сейчас как наорёшь и снова я обижусь =)
ну.. я его показал для своего текущего весьма увесистого, но к сожалению закрытого (показать не могу), проекта. =) А так — если например не использовать локали внутри приложений — у меня автоматом это из общих локалей браться будет. Если не использовать тонну своих библиотек — то и лишнего в /pylib/ не будет. По крайней мере цель у меня была следующего характера: надо было чтобы билд не сильно отличался от исходников.. ведь все же питон язык интерпретируемый и перемешивать все файлы после изменения каждой строчки — бее.. А билдить в реалтайме все равно нужно — ибо у меня тут и си и ситон с пурексом.. Главное делать так чтобы сам по себе проект от лейаута не сильно зависил =)) Т.е. если вдруг будет идея что-то сделать по-другому — чтобы это не было мегасложно. Посему и абсолютные импорты с именем проекта в начале — нафик нафик. Хотя grep и сколько-то часов (но не дней) для довольно крупного проекта, при налиичии регрессивных тестов — ничтожная цена.
я вот кстати тоже с этим долго дрался. Все мне хотелось темплейты куда-нибудь выкинуть подальше. А дрался с setuptools и distutils. Я уже не помню все грабли на которые пришлось наступить, но точно знаю что теперь я темплейты не считаю таким уж “статическим” дерьмом без которого всё работать может =)))). На самом деле если пытаться делать приложения “detachable” как плагины — то при большом их количестве или старте нового проекта становится комфортнее (:
Так или иначе дело не только в темплейтах — ибо джанговские приложения ведь не только их использовать могут.. логично что то, к чему больше никто не захочет получать доступ (в отличие от графики, скажем, куда неплохо бы статик-сервер отправить) держать в самом ”сердце”.
Лол. :D В тот раз весело поговорили, да… :)
Их в любом случае надо нафиг, потому что оччень мешает. :-)
Я так и стараюсь, но темплейты всё равно выношу отдельно. Хотя бы потому, что я стараюсь их как-то структурировать директориями по приложениям, т.е. рендерить в “blog/post_list.html”, а не просто в “post_list.html”, и если ложить их в директории приложения, выходит “application/templates/application/some_template.html”. Это разит мою нежную душу прямо до скрипа, какая-то прямо противоестественная вложенность. :)
Статику само собой надо отделять, я думаю это и понятно, да и сделать иначе сложно. А вот для темплейтов всё как-то прямо так… Почему бы не добавлять имя приложения как директорию, если шаблоны лежат в приложении? Очень бы удобно было, имхо. И логично.
потому что например я пока не придумал способ в темплейт лоадере определять в каком приложении темплейт вызывается. Думал я, правда, не долго и немного над другой задачей — я хотел чтобы если запрашивается в приложении blabla темплейт index.html — то он чтобы сначала искал именно в темплейтах текущего приложения, а потом пропускал через другие темплейт-лоадеры. Но чтобы даже не пытался искать темплейты у других приложений.
Собственно, реализовывать это я буду 100%, ибо нам очень надо. Потом поделюсь (:
чтобы былопонятнее
надо чтобы если в blabla2 запрашивается index.html — чтобы он сначала искал его в blabla2/templates/index.html, а уж если не найдёт — то в templates/ общих. В текущей реализации джанги если стоит лоадер app_directories — то blabla/templates будет ваще выше в списке чем blabla2/templates — тем самым index.html возьмётся оттуда.
Иными словами — в джанге и так сейчас все делают мини-абсурд вида blabla2/templates/blabla2/index.html :) Так что по-другому и не выйдет.
Да, я понял как. Я наверное сам пороюсь, на тему осуществления своей идеи с загрузчиком.
Comment form for «Расположение файлов в проектах Django»