wiz 15.12.2010 21:29

PythonСкелет Django-проектов

За вот уже 5 лет работы с джангой (с самого открытия код, ага) я уже столько раз делал ./manage.py startproject что уже и не счесть. И каждый раз это сопровождалось кучей рутинных операций типа настройки бд, созданием одних и тех же приложений. Первое время сама джанга менялась очень быстро и как-то это зафиксировать было практически нереально. К тому же фактически небыло инфраструктуры приложений, репозиториев и прочей обвязки. Но сейчас ситуация намного лучше.

Поэтому, представляю недавно собраный скелет типового джанго-сайта. Две команды и получается готовый сайт-со-страницами, готовый к навешиванию мясца.

Это не просто куча кода, но и некоторые решения из практики. Эти фичи я отметил по тексту жирненьким.

Репа с кодом: https://code.launchpad.net/~wiz/+junk/dbones
Лог работы: http://dumpz.org/25701/

Что внутри?


Весь проект лежит в системе управления версиями bzr. Сразу же, что избавляет от кучки «Initial import».

Используется virtualenv — система разграничения установленых пакетов и их версий. Это значит, что при обновлении системных либ (например) у вас не развалится (внезапно) работавший пару лет сайт. Внутри virtualenv свой питон, установлен уютненький pip, оболочка ipython и дебаггер ipdb.

Структура каталогов имеет смысл™, а не просто всё-в-куче, как это обычно бывает. сам джангопроект лежит в подкаталоге project, media лежит рядом, всякий хлам от virtualenv в venv.

В наличии скриптик buildenv.sh, который инициализирует venv, ставит туда все указаные в pip-reqs.txt питонопакеты и создаёт тестовую sqlite базу для разработчиков.

В media уже залиты css и js от проекта html5boilerplate, а в главный html-шаблон сайта встроены блоки и {{ SITE_MEDIA }}.

Урлы и settings уже настроены и готовы сразу к показу страничек и статики.

В "главном приложении" core есть моделька Pages с простенькими страницами, но она умеет их рендерить из всяких разных разметок (markdown, wiki, и другие).

Для остальных приложений заготовлен пакет apps, а для всякой внешней хрени пакет ext. Всякие мелочи жизни живут в utils.

Кстати о мелочах. При установке сразу ставится django-annoying, который настоятельно рекомендуется использовать при первой же возможности вместо изобретения велосипедов.

Для кэширования и сессий используется Redis. Что сразу же благоприятно сказывается на req/s. Ещё на него можно повесить работу с очередями задач celery, но это надо далеко не для каждого сайта и делается в общем-то одним pip install django-celery. Если у вас шаред хостинг или ещё как-то редис недоступен, то вам не повезло и придётся из settings убрать четыре строчки.

Для хранения настроек зависящих от места размещения используется settings_local.py который пытается импортироваться из главного.

Чего нету?

Я ещё не определился с системой тестирования. Штатная джанговская хороша, но nosetests лучше. Там штук пять вариантов интеграции и я пока не рассматривал особо.

Нет «поддержки» грядущего Django 1.3, но там довольно много изменений и может быть придётся даже перекапывать весь скелет под ноль.

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

Новые версии буду выкладывать по мере работы со своим “рабочим” проектом.


Тэги: django python
+ 18 -
Похожие Поделиться

bosha 15.12.2010 23:17 #
Огромный, жирный плюс автору. Сейчас активно "курю" django и наработки которые выложил автор я хоть и нашёл мало полезными для себя и своих проектов, зато приёмы и некоторые вещи которые используются взял на вооружение.

Вообще помучить бы автора чтобы подробнее описал или чтобы пост написал. Думаю раз человек работает с django с самого его появления, то ему есть много о чём рассказать :)
wiz 15.12.2010 23:20 #
Помучай, я как-то так сразу не знаю за что браться. Я что вижу, о том «пою» — вчера проект свой начинал, заодно и решил поделиться.
bosha 15.12.2010 23:28 #
Например мне бы было интересно почитать про Redis, я мельком о нём слышал что-то, но толком ещё не разбирался. Или чем nosetests лучше обычной штатной системы тестирования. В крайнем случае даже было бы сделать пост по данному скелету. Например почему структура именно такая и никакая другая. Я понимаю что так может быть удобнее, но чаще всего это обычно обосновано какими либо факторами :) В общем и т.д. Очень много всего. В рунете почти нет документации по django кроме djbook разве что, но там тоже очень многого нет..
wiz 15.12.2010 23:34 #
Про Redis всё очень просто - я запустил бенчмарк девсервера - 10 запросов в секунду. Включил редис - 20 запросов в секунду. Профит! И всего-то ничего делов (=

Больше мне пока не интересно, но планирую задействовать его непосредственно как дополнение к SQL базе данных, как приступлю, так и пост напишу.
wiz 15.12.2010 23:37 #
Структура каталогов может быть любой в общем-то, мне понравилось так расположить запчасти, кому-то ещё покажется удобней другой layout.

У меня во многих ранних проектах была куча-мала и это смотрится всё очень некрасиво, когда рядом с исходниками лежит заливаемое юзерами барахло например или там всякая статика.

Ближе к концу жизни проект так зарастает всяким хламом, что при ls или там bzr status хочется всплакнуть.
bosha 15.12.2010 23:49 #
Это был не самый удачный пример о чём написать ) Это понятное дело что не красивое. Я как-то на форуме на каком-то встречал человека, который очень любил помещать /media/ в templates и обосновывал это какой-то своей непонятной, магической логикой. Может поэтому этот вопрос у меня первый в голове появился :)
wiz 16.12.2010 00:08 #
Ну он наверно большой любитель поправить html в визуальных редакторах, чтобы из media туда сразу стили подтягивались. У нас, бородатых линуксистов, такая роскошь бывает редко. Да как-то и не хочется (:
bosha 16.12.2010 00:11 #
Визуальные редакторы зло. От них вреда больше чем пользы. Vim + сниппеты рулит )
wiz 15.12.2010 23:38 #
Про методики тестирования и всякие моменты из практики я думаю рассказывать в постах RANUX и после нового года, когда вновь вернусь к обучению студентов в нашей конторе.
bosha 15.12.2010 23:41 #
Стало интересно что за конторка где учат django =)
wiz 16.12.2010 00:09 #
Сейчас такая ситуация с кадрами, что народ не знает нихрена даже после 5-6 лет в универе. Приходится сразу брать на стажировку и медленно учить самим.
bosha 16.12.2010 00:13 #
Кстати ситуация весьма интересная ещё и тем, что есть множество кадров которые вроде как и не глупые и не плохо разбирающиеся в определённых вопросах, но у них нет высшего образования и их отфутболивают в пользу тех, у кого есть высшее, но они, извините идиоты. Сталкивался с этим не раз. Не как человек который принимает, а как тот кого принимают :)

Жаль, я думал курсы есть. Я бы может сходил. Хотя вряд ли, Вы наверняка в ДС =)
wiz 16.12.2010 00:43 #
Хуже, мы в замкадье, хоть и не таком далёком.
bosha 15.12.2010 23:52 #
Вот кстати чертовски интересно почитать было бы ajax, jquery в django проектах. Насколько я знаю (а знаю я мало. С django мало общаюсь, ну очень очень мало) там два разных способа работа с ними.
Elvis 16.12.2010 00:31 #
http://dajaxproject.com/ - Ajax на Django за 2 минуты (правда с coffeescript не работает)
bosha 16.12.2010 09:56 #
Спасибо конечно, но это не совсем то, что я имел в виду :) Такие готовые решения можно нагуглить очень быстро, собственно как и всякие how-to как сделать что-то конкретное. А мне куда интереснее теоретическая часть. Какие способы есть, в чём их преимущества и недостатки и т.д.
Elvis 16.12.2010 10:29 #
Ну вообще есть готовый декоратор @ajax_response

А так, основные моменты которые я придерживаюсь:
- все ajax ф-ции в файле /ajax.py
- все url'ы для них имеют name _ajax_
- все ajax возвращают {'status': 'ok|error', 'response': ...}

Можно пойти дальше и написать свой ajax decorator который перехватывает исключения при вызове ф-ции и автоматически возвращает {'status': 'error', 'response': str(exception)} и {'status': 'ok', 'response': ...}, если ф-ция при выполнении не выбросила исключения.

Так как яваскрипты лежат в отдельных файлах и не имеют доступа к Django templatetags, то перед всеми скриптами в документе я вставляю простой inline яваскрипт вида var SOME_URL = {% url app_ajax_func; %} , а в самом скрипте пользуюсь этой переменной в качестве адресата ajax запроса.

Elvis 16.12.2010 10:31 #
Парсер сожрал часть моего кода :(
Дублирую:
- все url'ы для них имеют name appname_ajax_funcname

wiz 16.12.2010 12:30 #
"аякс" декоратор есть в django_annoying
bosha 16.12.2010 12:37 #
Спасибо, но я не на столько плохо знаком с django чтобы не найти декоратор =)
bosha 16.12.2010 12:38 #
Спасибо =)

Для меня сейчас остро строит вопрос интеграции ajax'а..
Elvis 16.12.2010 00:35 #
Что могу посоветовать из своего опыта...
settings - это папка с
__init__.py - основные настройки
current.py - симв.ссылка
local.py - для локальной разработки
production.py - для деплоймента

apps - папка, содержащая все приложения проекта

media переименовать в static

в urls.py добавить StaticServe

неплохо было бы Jinja с темпплейтлоадером и какой-нибудь media generator
Может потом как нибудь свой skel выложу..
wiz 16.12.2010 00:44 #
А как переключаться между local/production сеттингсами? Мне это ещё только предстоит включить в свой скел.

static нелюблю, как-то привычней (ещё с первых версий джанги) media.

StaticServe у меня через миддлварь из annoying - она сама со всем разбирается и ничего настраивать не надо.
Elvis 16.12.2010 08:41 #
Переключаться просто - на продакшне делаешь rm current.py && ln -s ./production.py ./current.py

static затем, что бы MEDIA_URL не конфликтовал с ADMIN_MEDIA_PREFIX (иногда такие казусы случаются, если они оба на /media/ начинаются)...

В local.py обязательно надо внести ConsoleBackend в кач-ве EmailBackend и "dummy://" в кач-ве Cache Backend'а.

Так же советую настроить логирование в ./logs/django.log и заранее создать папку logs/

Было бы неплохо заиметь готовый .hgignore

Если прикрутишь Jinja+Hamlish + SaSS + CoffeeScript, то вообще красота будет.
wiz 16.12.2010 12:27 #
а что плохого что admin_media_prefix будет «начинаться» с media_url? У меня в медию делается симлинк на джангу из venv и всё ок.
Elvis 16.12.2010 13:07 #
Были проблемы при интеграции grapelli - не грузилась статика из grapelli по этой причине.
wiz 16.12.2010 12:27 #
А что есть "настроить" логгирование? Насколько я помню логи будут только в 1.3
Elvis 16.12.2010 13:09 #
Это значит написать что-то вроде:
#--- logging
LOG_DIR = os.path.join(PROJECT_ROOT, 'logs')
LOG_FILENAME = os.path.join(LOG_DIR, 'django.log')
LOG_LEVEL = logging.DEBUG
LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
if not os.path.exists(LOG_DIR):
os.makedirs(LOG_DIR) # We have to check, since logs/ is in .hginore.

wiz 16.12.2010 13:11 #
А оно thread/multiprocess safe? Если честно, ещё ни разу не сталкивался с необходимостью использовать logging питонячий. Это явно не типовое что-то (;
Elvis 16.12.2010 13:54 #
С некоторых пор я использую logging всегда после:
- строчек содержащих слово except
- в случаях когда вьюха возвращает response с кодом отличным от 200
- в исключительных / нестандартных ситуациях
- в целях debug'а

Это здорово облегчает жизнь тем, что уменьшает количество ошибок и ускоряет разработку.
wiz 16.12.2010 12:29 #
.hgignore у меня называется .bzrignore (=

jinja не пользуюсь, остальным как-то тоже. Посадить дизайнеров на скрипты генерирующие стили мне наверно ещё не скоро удастся...
rb 16.12.2010 19:34 #
А давай подружим наших скелетов? :)
Я недавно тоже написал обвязку для быстрого создания типового проекта (в моём случае PHP + движок CodeIgniter, и авторизацию с i18n добавлю).

Суть идеи в том, чтобы человек набрал "mkprj projectname" и получил готовый настроенный шаблон. mkprj у пользователя состоит из баш-скрипта и архива со статичной частью скелета. Чтобы можно было собрать заготовки для любых проектов, будь то PHP, Ruby, Django, C++ или что угодно ещё.

У меня скрипт генерирует структуру каталогов (хотя в принципе эту часть можно и в архиве держать, но решил пока так оставить), создает наборы девелоперских и продакшн конфигов и подготавливает заготовки SQL скриптов для базы, конфиг(и) апача и хедпер для его перезапуска.

Мне это экономит 1-2 часа работы и "несколько initial коммитов", как ты отметил :)
rb 16.12.2010 19:38 #
Забыл линк: http://code.google.com/p/mkprj/
wiz 14.01.2011 11:12 #
скелет проектов для Google App Engine