пятница, 8 ноября 2013 г.

Django 1.6

Вышла новая версия Django 1.6.

В Django 1.6 появилось новое API для работы с транзакциями. Начиная с этой версии привычные для работы с транзакциями функции autocommit(), commit_on_success() и commit_manually() из модуля django.db.transaction теперь считаются устаревшими и останутся для совместимости до 1.8. На их замену приходит atomic().

Ранее ключевым моментом был механизм управления поведением при работе с коммитом транзакции - автокоммитом, когда каждый SQL-запрос начинает транзакцию и коммитит ее автоматом, или ручным коммитом (COMMIT; SQL-запрос отправляется самостоятельно). Этот механизм довольно хорошо работал в случае независимых транзакций, но вот в случае вложенного использования устаревших функций результат мог быть некорректен. Например, если у нас есть 2 блока  commit_on_success(), вложенных один в другой, то может возникнуть ситуация, когда результат выполнения внутреннего блока будет закоммичен, поломав атомарность внешнего блока.

Теперь же во-первых Django 1.6 по умолчанию включает режим автокоммита. И единственным механизмом работы с транзакциями становится atomic(), который не боится вложенности. Также вместо TransactionMiddleware доступна конфигурационная константа ATOMIC_REQUESTS, при установке значения которой в True (дефолтное значение — False), джанго будет стараться обработать один HTTP-запрос в одной транзакции. То есть, если выполнился запрос без каких-либо проблем, то закоммитили, нет - откатили изменения.

Необходимо отметить, что atomic() может использоваться как декоратор, так и как менеджер контекста:

from django.db import transaction

# декоратор
@transaction.atomic
def viewfunc1(request):
    # этот код будет выполнен внутри транзакции
    do_stuff()
and as a context manager:

# менеджер контекста
def viewfunc2(request):
    # этот код выполняется в режиме автокоммита
    do_stuff()

    with transaction.atomic():
        # а здесь уже выполняется внутри транзакции
        do_more_stuff()

В Django 1.6 были добавлены постоянные соединения с базой данных. Это, конечно, не пулл соединений, так как они изолированы потоками, в которых запущено приложение, но, это уже гораздо лучше, чем постоянное подключение к базе при каждом HTTP запросе. Время жизни соединений регулируется конфигурационной константой CONN_MAX_AGE.

В Django 1.6 появился новый механизм для запуска тестов: django.test.runner.DiscoverRunner, который использует логику поиска модулей с тестами из unittest2. Теперь тесты могут располагаться в любых модулях, если имя файла, содержащего их соответствует маске test*.py. Правда, при этом, тесты из models.py и tests/__init__.py найдены и запущены не будут. Самым простым решением является переименовывание их в что-либо вида test_models.py и tests/test.py. Помимо этого доктесты больше не будут подгружаться автоматом. Но их будет не сложно включить обратно, следуя указаниям из документации по unittest.

У management-команды ./manage.py test теперь появилась опция --pattern, указав которую, можно менять маску для поиска файлов с тестами.

Команда django-admin.py check теперь позволяет проверить совместимость проекта или приложения с текущей версией Django, выдавая оповещения в случае нахождения несовместимых мест. Предполагается, что эта команда будет помогать при переходе на новые версии фреймворка.

В Django 1.6 добавились улучшения ORM. Теперь QuerySet поддерживает синтаксический сахар в виде методов first() и last(), а также earliest() в дополнение к latest(). ORM теперь поддерживает hour, minute и second в дополнение к добавленным ранее year, month и day при поиске по полям с датой и/или временем.

Django 1.6 - это последний релиз Django, в котором еще поддерживается Python 2.6. Со следующего релиза Django будет требоваться как минимум Python 2.7.