Разумная альтернатива Django

Александр Соловьëв

Кто здесь?
• 4 года опыта работы с Django
• Автор и мейнтейнер Byteflow
• И всë такое

Django — это клëво
• Детерминированность окружения
• Модульность приложений
• Документация

Ложки дëгтя
• ORM
• Templates
• URLs
• Forms
• Команды

Django ORM
• Никаких проблем, пока всë просто
• Сырой SQL, когда всë сложно
• Не элегантно, но можно

SQLAlchemy
• Чуть более многословная
• Простые случаи — многословнее, чем в Django
• Управляется со сложными случаями

Django Templates
• Скорость — низкая
• Деградирует от вложенности (extends/include)
• Ограниченность синтаксиса
• Прячет Exception’ы
• Низкоуровневый парсер

Jinja2
• Похожа на шаблоны Django
• Скорость — высокая
• Возможности — пошире
– {{ dict[key] }}
– {{ data|filter(oh, my) }}
– даже в Django уже сделали почти нормальный if ;-)
• Templatetag’и — сложнее
• Макросы!

Макросы в Jinja2
{% macro render_post(post) %}
<time>{{ post.time }}</time> {{ post.title }}
{% endmacro %}
{% block content %}
<h1>{{ render_post(posts[0]) }}</h1>
{% for p in posts[1:] %}
<p>{{ render_post(p) }}</p>
{% endfor %}
{% endblock %}

urlresolvers vs Werkzeug
• Простой пример
url(r'(?P<name>\w{3,})', view)
Rule('<name(minlength=3)>', view)

• Конверторы: '<int:id>', '<float:value>'
• Код легко читать и расширять

Django forms
• Неприятная смесь логики и представления внутри
• Слегка странный API
(например clean_<fieldname> не принимает значение)
• Тяжело строить сложные формы

WTForms
• API очень похож на django.forms
• Но чище (как и код внутри WTForms)
• Сложные случаи легко решаются
– FormField
– FieldList

Команды
• Привет, Java! 1 команда — 1 модуль
• Каждая команда — класс
• Тяжеловесно
• Многословно
• Неудобно

Opster
@command(usage='[-l HOST] [-p PORT]')
def runserver(listen=('l', 'localhost', 'ip to listen on'),
port=('p', 5000, 'port to listen on'))
'''Run development server'''
print 'Success'
> ./yourscript help runserver
yourscript runserver [-l HOST] [-p PORT]
Run development server
options:
-l --listen
-p --port

ip to listen on (default: localhost)
port to listen on (default: 5000)

Выводы
• Отдельные проекты лучше
• Любой из них можно использовать с Django
• Но что останется от неë самой?
• И сторонние приложения не готовы к этому

Svarga
• Меньше 2 тысяч строк
• Django-like look&feel
• Глобальное окружение
• Батарейки

Глобальное окружение
from svarga import env
from svarga.shortcuts import as_html
@as_html('hello.html')
def hello():
return {'name': env.request.args['name']}

Глобальное окружение
• env.(settings | request | sqla | jinja | user | ...)
• Окружение доступно отовсюду
• request — это запрос (а не солянка, как в Django)
• Практично

Приложения
• Просто пакеты а-ля Django
• С опциональной инициализацией:
app/__init__.py:
def init(settings, env_class):
settings.add_template_path('blog', 'templates')

template:
{% extends "blog/base.html" %}

Модели
• Изначально — прослойка над SQLAlchemy
• Поддерживают разные бекенды
– GAE
– MongoDB
– любой другой
• Нет общего API запросов
• Генерация метаданных (например, для ModelForm)

Декларация моделей
class Card(Model):
number = models.IntegerColumn()
class Question(Model):
card = models.ForeignKeyColumn(Card, backref='questions')
number = models.IntegerColumn()
class Answer(Model):
question = models.ForeignKeyColumn(Question, backref='answers')

SQLAlchemy FTW
q = (Question.objects
.eager(Question.card, Question.answers)
.filter_by(number=number)
.join(Card).filter_by(number=card)
.one())

Батарейки
• Сессии
• Аутентификация
• Админка (в процессе)
• Bundle'ы

Bundle
from svarga.shortcuts import as_html, bundle
class TestBundle(bundle.Bundle):
@bundle.expose('/')
@as_html('test/entry.html')
def entry(self):
return {'param': 'eter'}

Bundle
from svarga.core.routing import Map
from views import TestBundle
urls = Map(
TestBundle('name1', '/prefix1'),
TestBundle('name2', '/prefix2'),
)

Админка
• Основана на bundle'ах
• Требует декларации
class SampleAdmin(ModelAdmin):
class Meta:
menu = ['Sample Admin', 'Test']
model = Sample

• Легко расширяется

Небезупречно
• Нас мало
• И документации тоже
(но библиотеки документированы)
• Тестов нет :(
• Готового кода немного
• Нет крупного коммерческого проекта за плечами

Утешение
• Нет застоя
• Использовать не страшно — кода немного
• Я рассказал не про все плюшки
(не забывайте об отладчике из Werkzeug ;-)

Welcome
• http://svarga.piranha.org.ua/
• irc://freenode.net/#svarga
• svarga@librelist.com