Шаблон проекта на Джанго с инструментами сборки и утилитами

Иногда приходится создавать с нуля сайт на Джанге. Это и тесты концепций, и простенькие странички (ведь если мы в проекте используем разные мощные инструменты, почему бы сайт-визитку не сделать тоже с их помощью, избавив себя от ручной работы?).

Итак, представляю публике проект под девизом «Поменьше писанины! Побыстрей, дебаг!» Набор для скоростной разработки на Джанго.

Это 2 шаблона:
  • шаблон конфига buildout, который подтягивает и собирает все необходимые проекту пакеты
  • шаблон проекта, а именно настройки, включающие все нужные инструменты, и набор статики (готовые файлы на Haml и Sass)



Установка



Чтобы загрузить проект и создать проект на Джанго, просто выполните команды:

$ hg clone ssh://hg@bitbucket.org/siberiano/fastdev-django my_new_project
$ cd my_new_project
$ rm .hg/hgrc
$ python bootstrap.py --distribute
$ make buildout


(Страница проекта на BitBucket.)

Из чего состоит проект:

Makefile


Вместо набора скриптов командной строки мы в проекте с моей работы сделали Makefile и составили зависимости команд, например, что run можно выполнить только после buildout и bootstrap. Я добавил в make следующие рутинные процедуры:

  • run — запускает сервер на 0.0.0.0:8000
  • shell_plus — запускает расширенную командную строку Джанго
  • make_messages — составляет файл locale из html и haml
  • compile — компилирует перевод


Buildout


zc.buildout — это скрипт, разработанный в проекте Zope и используемый в Pylons, который собирает в папке проекта или в пользовательской папке ~/.buildout, изолирует окружение проекта от дополнительных пакетов (site packages) и выполняет некоторые рецепты (например, установить скрипт и поставить на него линк из другого).

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

Вот пример простейшей конфигурации, где мы устанавливаем Джангу с дополнительными пакетами и статический анализатор кода pyflakes:

[buildout]
parts =
    django
    pyflakes
 
[django]
recipe = djangorecipe
eggs = 
    ipython
    django_extensions

[pyflakes]
recipe = zc.recipe.egg
scripts = pyflakes
eggs = pyflakes
entry-points = pyflakes=pkg_resources:run_script
arguments = 'pyflakes', 'pyflakes'


Buildout скачает со специального сайта рецепт djangorecipe и zc.recipe.egg и выполнит их.

Самый интересный для нас — djangorecipe. Этот рецепт делает обёртку вокруг скрипта manage.py, которая изолирует его от дополнительных пакетов, установленных в системе и подключает к нему только яйца, указанные в конфигурации buildout.

Такая конфигурация избавляет нас от нескольких головных болей:

  • мы где-то можем указать, какие яйца нужны, и они на любой новой системе, например, хостинге, установятся автоматически и одной (!) командой
  • можем быть уверенными, что на всех системах будут отложены яйца одинаковой версии (возможно даже более старой, но гарантированно работающей)


Установка проекта делается в 2 команды:

$ python bootstrap.py --distribute
$ bin/buildout


Проект готов, и сервер Джанго для разработчика уже можно запускать. Вместо manage.py [команда] делаем

$ bin/django runserver 0.0.0.0:8000


Батарейки


Но удобная система сборки проекта — далеко не всё, что нужно для ускоренной разработки. Не спешите запускать свеженаписанный код. Выполните проверку статическим анализатором. Очень много ошибок им отлавливаются сразу.

$ bin/pyflakes my_new_script.py
Undefined variable: test_string, line 2
Variable used before definition: another_var, line 5


(Обращение к 2 переменным, которые не были объявлены. Без анализатора мы бы дважды запускали сайт и видели баги.)

После анализаторов программистам нужны дебаггеры. Их в Питоне есть масса, но из тех, что мы проверили в команде, самый удобный — PuDB, это интерактивная среда, которая работает как Midnight Commander в текстовом режиме и напоминает старые добрые QBasic или борландовские среды из 80-х годов.

Дебаггер PuDB

Чтобы его запустить, нужно вставить команду там, где требуется отладка:

import pudb; pudb.set_trace()


внутри дебаггер очень хорошо настраивается (Ctrl+P), и из него можно также зайти в консоль отладки на IPython. Это мощная консоль Питона с автозавершением всего, что можно, и макросами, чтобы записать и повторять какие-то действия, например, отлаживая модули.

Ещё один очень полезный инструмент — панель отладки, или Django Debug Toolbar. По ссылке прямо в выданной странице есть панель со всеми параметрами построения страницы, списком шаблонов и переменными всех контекстов. Если страница не «упала», но выводит что-то не то, не нужно править код, можно просто посмотреть контексты.

Что же если страница падает? Обычно, если там происходит какая-то неясная ошибка, нужно сделать следующее:

  • открыть файл программы в редакторе, вставить строку pudb
  • подождать перезапуска сервера (что может быть долго на толстом проекте)
  • открыть броузер, нажать «обновить»
  • перейти в консоль и начать дебажить
  • найдя ошибку, надо вернуться в файл и убрать строку дебага


Если же в проекте установлен Werkzeug, вместо 5 действий нужно сделать одно, потому что это приложение выдаёт консоль посмертной отладки прямо в окне броузера. Причём в любом уровне стека вызова! Для многих проблем этого вполне достаточно.

Если код работает как надо, его нужно причесать для читаемости.

$ bin/pep8 my_new_script.py
'Import *' is very bad style. Line 2
Expected 2 blank lines, found 1. Line 5.


HAML, Sass, OOCSS

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

HAML — это, по сути, язык XML, очищенный от мусорных символов, и в нём есть значимая табуляция. Если вы программируете на Джанго, значит вы знаете Питон и его табуляцию. Аттрибуты тэгов пишутся как JSON, тэги Джанго поддерживаются, некоторые даже автоматически закрываются:

- load i18n compress
%html
    %head
        %title
            - block title
                Скоростная разработка в Джанго

    %body
        #menu.page.oldSchool
            - block menu
                .line.title_bar
                    .unit.size1of2
                        %a.site_logo{'href': "/"} Скоростная разработка в Джанго
                
                    .unit.size1of2.lastUnit
                        - include 'language_selector.haml'
    
        #body
            - block body


Он преобразуется в такой документ:

{% load i18n compress %}
<html>
    <head>
        <title>
            {% block title %}
                Скоростная разработка в Джанго
            {% endblock %}
        </title>
    </head>
    <body>
        <div id="menu" class="page oldSchool">
            {% block menu %}
                <div class="line title_bar">
                    <div class="unit size1of2">
                        <a class="site_logo" href="/">Скоростная разработка в Джанго</a>
                    </div>
                    <div class="unit size1of2 lastUnit">
                        {% include 'language_selector.haml' %}
                    </div>
                </div>
            {% endblock %}
        </div>
    
        <div id="body">
            {% block body %}
            {% endblock %}
        </div>
    </body>
</html>


Сколько раз у вас разваливалась вёрстка из-за не там закрытого тэга? В языке HAML закрывающих тэгов нет. Теги закрываются там, где кончается уровень табуляции. Такой документ проще править и добавлять уровни вложенности, и проще читать — в нём в 1,5 раза меньше строк и на четверть меньше букв. Единственный проигрыш в символах — JSON для аттрибутов, но это не большая потеря.

В этом проекте используется HamlPy, который, как видно из листинга, поддерживает тэги Джанго и обычный HTML, если языка Haml вам будет недостаточно, например:

<option {% if option.selected %}selected{% endif %}>{{ option.value }}</option>


Аналог Haml для CSS — язык Sass. В проекте Sass поддерживаются 2 вида разметки: SCSS (аналог CSS с фигурными скобками) и SASS (аналог Haml и Питона, с табуляцией). Я предпочитаю последний как более лаконичный. Самый большой выигрыш от Sass — сжатие всех проприетарных правил, как *-linear-gradient, в один вызов:

@import bourbon
    .action
        +linear-gradient(top, #6db3f2 0%, #54a3ee 50%, #3690f0 51%, #1e69de 100%)


Развернётся в большой список со всеми реализациями градиента (-moz-..., -o-..., -webkit-… и т.д.). Здесь пример не привожу, но скажу только, что язык Sass поддерживает циклы и условные блоки @if… else. Существует аналогичный проект Less-CSS, и его при желании тоже можно подключить к django-compressor, но он не позволит делать такие манипуляции, как циклы и перегруппировки аргументов.

Стили можно вкладывать один в другой:

.class1
        font-weight: bold
        > .class2
            font-style: italic


Результат:

.class1 {
        font-weight: bold; }
    
    .class1 > .class2 {
        font-style: italic; }


Object Oriented CSS — замечательный проект Николь Салливан, в котором она сумела обуздать разростающиеся, как плесень, правила, объединила и обобщила некоторые базовые приёмы и получила очень компактную разметку. Если вы не знакомы с OOCSS, посмотрите её выступления (на английском) и примеры кода с сайта проекта.

Вот самые ходовые заготовки. Таблицы (в разметке HAML):

.line
    .unit.size1of3 левая колонка
    .unit.size1of3 центральная колонка
    .unit.size1of3.lastUnit правая колонка


«Медиа-блок», то есть картинка слева и текст, не обтекающий картинку, справа:

.media
    %img.img{'src': '{{ message.author.picture.url }}'}/
    .bd= message.text


Есть также заготовка шаблона страницы, блок контента (прямоугольник с шапкой, телом и основанием). В моём проекте OOCSS встроен как суб-репозиторий, и его можно периодически обновлять с ГитХаба.

Что добавить


Пока что проект представляет собой репозиторий Mercurial, и ваш новый проект будет привязан к моему репозиторию. Я советую удалять hgrc. Возможно, следует сделать более удобный инсталлятор. Чтобы исправить этот недостаток, клонируйте проект и присылайте ваши запросы на слияние.

В ближайших планах:

  • добавить в статические файлы библиотеки на JavaScript: RequireJS, jQuery и Backbone (причём тоже в виде суб-репозиториев)
  • добавить приложение Rebuild Db, обновляющее базу данных и загружающее «рыбу» (fixtures), чего не может делать syncdb
  • приложение TemplateFlakes, статический анализатор шаблонов, загруженных и используемых тегов
  • примеры шаблонов
  • Добавление: за неделю с написания до публикации статьи, была добавлена команда bin/buildout webfaction, которая устанавливает скрипт WSGI, чтобы проект работал на одноимённом хостинге.


Буду рад отзывам, форкайте проект, присылайте запросы на слияние.

Добавление: на ВедреБитов попросили добавить инструкции по установке сторонних компонент. Отвечаю: сторонние компоненты вручную устанавливать не надо. SASS, Pyflakes и другие приложения установит buildout.

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 19

    +1
    Хорошая сборка, спасибо.
      0
      отлично… как раз приходится начинать изучение :)
        +12
        тогда сборкам нет
          +1
          Да, изучать лучше начинать с самой минимальной конфигурации, Джангу — лучше без сборки.

          Сборку с buildout мне показали в проекте, где я работал. Когда понадобилось сделать её самому, я долго мучался и правил чужие, но в конце концов взял и прочитал доки, начиная с самой простой конфиуграции.
            +1
            Уф… Мне бы, самое основное, мозг сломать в сторону окружений Python'a после «пыха»… это самое сложное у меня по ходу. Само программирование, более-менее прозрачное, пробовал просто уже. Выбрал тут небольшой проектик и пытаюсь его написать, вместо переписывания очередного «бложика» из документации. В любом случае пасиба! :)
              +1
              Тогда могу посоветовать писать реальный проект, сборка поможет. А чтобы разбираться в Джанге, можно задавать вопросы, искать готовые пакеты. Их можно подключать в buildout.cfg. А если чего-то не хватает, писать самому. Для этого надо лезть в исходники самой Джанги, чтобы понять, что и как дорабатывать.
        +2
        Спасибо большой за статью. Не знал, что уже появилось нечто вроде HamlPy. Думал, что по-прежнему есть только не сильно юзабельный shpaml.

        Копнул чуть глубже и открыл для себя djaml (https://github.com/chartjes/djaml), который позволяет интегрировать HamlPy в Django, то есть по сути приближайет поддержку HAML в Django к виду, аналогичному RoR. На мой взгляд за этим будущее. Там пока, судя по всему, есть проблемы, например шаблоны не кешируются. Вы не пробовали использовать djaml?
          0
          Именно он используется в проекте.
          0
          Насчет использования Make — ужас. Вы просто заменили одни команды, другими.
            +1
            Нет, не ужас. Вместо последовательного набора

            python bootstrap.py --distribute
            bin/buildout
            bin/django rebuilddb (или syncdb)

            я просто делаю

            make rebuilddb

            Кричать «ужас» всякий умеет. Если у вас есть другое, элегантное решение, присылайте, применим.
              0
              alias rebuilddb='python bootstrap.py --distribute;bin/buildout;bin/django rebuilddb'

              Я же предпочитаю fabric. писать fab на 1 символ меньше чем make :D
              0
              Также давным давно использую Makefile для шорткатов на действия с проектом. Что в этом плохого?
                0
                Не только шорткаты, ещё можно прописывать зависимости (вот документация).
                  –1
                  Делать команды — фигня. Можно shell скрипт тогда накатать, разницы ни какой. А вот если бы сделали для make all зависимость от языков, что бы если языки меняются то пересобирало при деплое — другое дело. (ну и всякие такие вот мелочи-вкусности)

                  all: mo
                  buildout foo

                  mo: local/ru/.../app.po
                  bin/django compilemessages
                  0
                  Вот пример:

                  run: bin/django syncdb bin/sass
                  bin/django runserver 0.0.0.0:8000

                  Команда run запускает разработческий сервер, но перед этим проверяет, установлен ли скрипт django, сделан ли syncdb, есть ли sass. Если их нет, они устанавливаются.

                  При этом её можно запускать сразу как только склонировали репозиторий:

                  $ hg clone…
                  $ cd myproject
                  $ make run

                  После этого их при желании можно вручную обновить:

                  make bin/sass

                  вызовет скрипт, который переустановит рубёвый пакет sass. Ну и другие зависимости.

                  Конечно, можно завести шеллскрипты и на них всё делать, но тогда каждый раз вам придётся проверять, всё ли установлено, или что-то надо обновить. Не знаю, как остальные, а я по незнанию когда-то написал такую выполнялку обновлений на питоне. Только оказалось, что это намного сложнее, чем кажется, и она не работала как надо. Поэтому там, где есть последовательности операций и зависимости, разумно будет полагаться на makefile.
                    –1
                    Не понимаю при чем тут тогда make, если он вызовет все равно скрипт который проверит у установит зависимости. Что я имел ввиду я описал в комментарии выше. А просто делать прослойку из make которая одни команды заменит другими — чур меня.
                      0
                      Так в том-то и дело, что make здесь не просто прослойка для замены скриптов. Зависимости в виде яиц питона — это одно, а зависимости операций внутри проекта — это другое.

                      syncdb можно делать только после того как есть скрипт bin/django. Поэтому в Makefile есть такое правило:

                      syncdb: bin/django
                      bin/django syncdb
                      touch syncdb
                      (touch делает файл, который как метка времени)

                      поэтому, повторяю, если у меня есть makefile, я могу склонировать проект и сразу запускать, например, syncdb. Make увидит, что нет bin/django и запустит развёртывание проекта.

                      Вы посмотрите в исходники прежде чем хаять.
                  +1
                  У каждого разработчика со временем подобный шаблон появляется, который он использует для своих проектов.
                    0
                    Верно. Но если такое происходит, надо подобные шаблоны как-то объединять и делать легко используемыми. Собственно, фреймворк Джанго — это тоже когда-то был просто чей-то шаблон проекта.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое