Что будет в django 1.3

Релиз django 1.3 совсем скоро. Думаю, многие уже RC в продакшне используют. Но все равно, пробегусь еще раз по тому, что нас ждет, стараясь не скатиться в перевод release notes.

django.contrib.staticfiles

Теперь можно организовывать статику (картинки, js, css и т.д.) точно так же, как организуются шаблоны: держать ее в папке приложения (особенно полезно для отдельных django-приложений) или в папке проекта, переопределять часть файлов, оставляя другие нетронутыми, ссылаться на файлы, не заботясь о том, куда их пользователь поместит или где он хранятся (отдельный сервер? amazon s3?), не нужно больше "руками" эти файлы выискивать и копировать в правильное место.

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

Тестирование

В джанге теперь живет unittest2, django.test.TestCase наследуется от unittest2.TestCase. Это означает, что можно писать тесты для джанги, используя все новые фичи из unittest2. Например, можно писать тесты заранее и помечать их декоратором expectedFailure. Или указывать условия, при которых тесты должны пропускаться (например, тесты, специфичные для mysql и не должны проходить под sqlite). Или использовать новые assert'ы.

Конечно, раньше можно было поставить unittest2 и использовать его, но это не помогало, когда была нужна база и наследоваться нужно было от django.test.TestCase.

Появились также разные полезные мелочи вроде assertNumQueries.

ForeignKey

Ура, теперь при удалении объекта, на который кто-то ссылался через FK, ссылающиеся объекты не будут обязательно удалены. Можно настроить каскадное удаление, сброс в NULL или значение по умолчанию, вызов исключения, ничегонеделание (позволить базе самой решать).

Шаблоны

Часто писали

{% with foo as bar %}
    {% include "my_template.inc.html" %}
{% endwith %}

или inclusion-теги для таких штук? Теперь это не обязательно, и кучу inclusion-тегов можно выкинуть будет:

{% include "my_template.inc.html" with bar=foo %}

Плюс к этому: можно загружать только отдельные теги из библиотек тегов; в url можно передавать переменные; тег with тоже упрощен; теги, созданные через simple_tag, научились принимать контекст.

Кеширование

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

Кроме того, из разных сторонних приложений с кеширующими бекендами в джангу переползли полезные фичи: теперь из коробки есть поддержка глобального префикса (нужен, если несколько проектов используют 1 memcached, чтобы избежать конфликта ключей), версий кеша (обновил сайт, а в кеше старые данные лежат, которые теперь в неправильном формате? увеличь текущую версию кеша), преобразования ключей (нужна хитрая схема инвалидации? реализуй), поддержка pylibmc, кеширования для GET-запросов с параметрами.

Журналирование

Интеграция с питоновским logging теперь есть. В settings.py можно журналирование гибко настраивать. Отсылка email'ов по 500 ошибкам наконец тоже сделана через logging.

Вьюхи

Для написания вьюх появилась куча разных полезностей.

Вьюхи, основанные на классах

Можно теперь писать вьюхи-классы. Для себя пока не понял, зачем они. Наверное, стоит использовать для каких-то "больших" штук, или когда какая-то сложная штуковина с замороченной логикой, которую нужно расширять в других местах (декларативный api? что-то уровня универсальной админки?). Стандартные generic views теперь переписаны на классах, чтобы их проще было расширять.

TemplateResponse

Для того, чтобы можно было расширять и обычные вьюхи-функции, в джанге теперь есть TemplateResponse. TemplateResponse - это ленивый HttpResponse, который рендерит результат (подставляет контекст в шаблон) только в самый последний момент. Если функция возвращает TemplateResponse, то у нее потом можно заменить шаблон, изменить (и прочитать) контекст, или вернуть совсем другое что-то (без накладных расходов на рендеринг исходного ответа). Эту штуку довольно легко пропустить в release notes и начать для гибкости наворачивать вьюхи на классах, поэтому пример:

# библиотека для работы с попугаями
# была написана профессором биологии в качестве материала к диссертации

from django.template.response import TemplateResponse
from parrots.models import Parrot

def parrot_list(request):
    parrots = Parrot.objects.all()

    # По умолчанию будет использоваться RequestContext.
    # Полотна с render_to_template и хаки с direct_to_template
    # теперь не нужны.
    return TemplateResponse(request, 'parrots.html', {'parrots': parrots})
# наш проект.
# parrot_list делает много всего крутого и полезного (еще бы,
# профессор биологии писал), мы хотим это повторно использовать,
# но некоторые вещи мечтаем поправить

import parrots.views

def parrot_list(request, color)
    # то, что функция возвращала по умолчанию
    response = parrots.views.parrot_list(request)

    # на данный момент шаблон еще не рендерился (TemplateResponse ленивый),
    # к базе обращений тоже еще не было (QuerySet тоже ленивый)

    # меняем шаблон на свой - данные, с которыми он будет рендериться,
    # пока теми же остаются
    response.template_name = 'my_parrots.html'

    # вытаскиваем профессорских попугаев
    original_parrots = response.context_data['parrots']

    # фильтруем их по цвету, добавляем хозяина попугая сразу в выборку
    response.context_data['parrots'] = original_parrots.\
                                filter(color=color).select_related('owner')

    # еще что-нибудь пусть в контексте будет
    response.context_data['foo'] = 'bar'

    # вот теперь все настроили как хотели
    return response

Generic views теперь возвращают TemplateResponse по умолчанию.

django.shortcuts.render

# профессор не хочет, чтобы материалами его диссертации пользовались

from django.shortcuts import render

def parrot_list(request):
    parrots = Parrot.objects.all()

    # render_to_response и direct_to_template теперь не нужны
    return render(request, 'parrots.html', {'parrots': parrots})

Это не все: кроме этих изменений, улучшена работа с i18n и l10n, из кода был убран весь мат, ну и еще много разных менее заметных изменений и архитектурных улучшений, о части которых можно почитать в release notes.

Note

Статья на хабре: http://habrahabr.ru/blogs/django/115763/