Category: общество

Category was added automatically. Read all entries about "общество".

eye light

Pyrant+Models. Svarga. Werkzeug. Glashammer. WTForms.

В последнее время между делом и досугом искал легкий веб-фреймворк для замены Django в части проектов. В качестве БД намереваюсь использовать Tokyo Cabinet через Pyrant+Models.

Сначала начал ковырять Svarga, потому что там есть хорошая задумка -- сквозные модели. Но пока получается, что интеграционного толку от них будет немного, а в таком случае, прыг-перепрыг, я могу воспользоваться просто связкой Pyrant и Models без дополнительных прослоек. Тем более, что админки там всё равно нет. Продолжил поиск. Выбор нынче довольно широк.

Попытка вернуться к истокам и взять CherryPy провалилась, потому что на нем можно спокойно писать только уж совсем примитивные веб-приложения (в т.ч. простые морды к сложным кишкам. Кстати, что за "перепрыг" в предыдущем абзаце?).

Далее -- Werkzeug. Сам по себе он прекрасен. Чего стоит пресловутый интерактивный отладчик в браузере -- там, где Django с удовольствием кидает невразумительное "template wrapped". Но одного веркцойга мало -- хочется писать встраиваемые приложения и не задумываться о некоторых механизмах, которые у Werkzeug торчат наружу. Поэтому народ пишет легкие фреймворки поверх Werkzeug. Вернее, народ пишет утилиточки там, утилиточки тут, копирует их туда-сюда, а потом терпение кончается и начинается фреймворк.

Например, Glashammer. (Glas Hammer, хотя я постоянно прочитываю его как "глашаммер".)
Из всех отсмотренных легковесных фреймворков с батарейками этот мне понравился больше всего. И документация, кстати, довольно хорошая.

Стек: Werkzeug + Jinja2 + WTForms.
То же самое мы видим в Svarga и ряде других вариантов.
Тенденция, однако. :)

Отличается Glashammer от многих других мини-фреймворков, в основном, деталями. Моделей там вообще нет (вернее, есть поддержка разнообразных внешних библиотек). Пожалуй, это даже хорошо, потому что разработчики, не навязывающие, но _предлагающие_ некоторый ORM, норовят слишком часто _подразумевать_ его. А тут заведомо открыто всё.

В перспективе, возможно, получится в Гласхаммере адаптировать подход Сварги к моделям и запросам.

А вот самое вкусное в Glashammer -- appliances. Можно вьюшки писать в стиле джанго, а можно создать класс и вьюшки определять как его методы. (С декоратором expose, как в CherryPy -- мечта джангонавта.) Так вот класс этот -- Appliance -- чрезвычайно удобен.

Если будет время, перепишу всякие сырые заготовки на этой штуке и выложу на битбакет. Есть подозрение, что получится быстрее, чем ковыряться с Django+RDBMS. Во всяком случае, отказ от схем (с переходом на Pyrant/Models) вызывает какой-то злорадный смешок при миграции. Никаких alter table, schemamigration, datamigration, migrate... ну в крайнем случае простенький одноразовый скриптик из трех-четырех строчек. И вообще, "миграции схемы" не существует -- есть либо трансформация данных, либо правка модели, которая определяет не полную структуру документа, а структуру нужной нам части базы. То есть, если надо -- выгребаем все документы с атрибутом "title" и не обращаем внимания на остальные атрибуты и "типы" документов (которых нет). И вот эту "выгребалку-проверялку-сохранялку" называем моделью. И, о да, оно работает с вебом. Совершенно, прыг-перепрыг, реактивно работает. О ура.

WTForms -- радость тоже. Во-первых, форкфлоу аналогичен тому, что в Джанге (а он разумен и прост). Во-вторых, никакой привязки ни к джанге, ни к каким бы то ни было моделям. Кстати, что опять за "перепрыг" в предыдущем абзаце? Тенденция, однако. Но вернемся к баранам, они ждут.
Может потребоваться генерация форм путем интроспекции модели -- тут, ессно, надо писать хелпер, ибо само оно в ваш ORM смотреть не будет. Для SQLAlchemy уже есть что-то, надо будет нацарапать аналог для Models. Но чтобы сохранить отвалидированную форму в экземпляр модели, достаточно и вот этого (привожу форму и вьюшку целиком):

class PageForm(Form):
    slug = TextField('URL part', [validators.required()])
    name = TextField('Title', [validators.required()])
    text = TextAreaField('Text')

@expose('/edit/<int:page_key>/')
def edit(request, page_key):
    page = db.get(Page, page_key)    # зная первичный ключ, ищем объект в БД
    form = PageForm(request.form, page)    # форма ничего не знает про модель
    if request.method == 'POST' and form.validate():
        form.populate_obj(page)      # и тут форма ничего не знает про модель
        page.save(db)                # откуда взяли, туда возвращаем
    return render_to_response('edit.html', form=form)


Смотрим внимательно: плевало оно на все ORM'ы, просто getattr/setattr и всё. А больше-то и не надо ничего. Всё гениальное просто...

Ну а про Jinja2, наверно, можно и умолчать. Вероятно, наиболее вменяемый шаблонизатор. И очень похожий на Django templates.