Примечания к выпуску Django 1.1

29 июля 2009 г.

Добро пожаловать в Django 1.1!

Django 1.1 включает в себя ряд новых возможностей new features, множество исправлений ошибок и простой путь обновления с Django 1.0.

Изменения в версии 1.1, совместимые с обратными изменениями

Django придерживается политики API stability. Это означает, что, в общем, код, который вы разрабатываете для Django 1.0, должен продолжать работать в 1.1 без изменений. Однако мы иногда вносим обратно несовместимые изменения, если они необходимы для устранения ошибок, и есть несколько таких (незначительных) изменений между Django 1.0 и Django 1.1.

Перед переходом на Django 1.1 вы должны дважды убедиться, что следующие изменения не повлияют на вас, и обновить ваш код, если они повлияют.

Изменения в названиях ограничений

Django 1.1 изменяет метод, используемый для генерации имен ограничений базы данных, чтобы имена были последовательными независимо от размера машинного слова. Это изменение является обратно несовместимым для некоторых пользователей.

Если вы используете 32-битную платформу, то вам ничего не грозит; вы не заметите никаких различий в результате этого изменения.

Однако пользователи на 64-битных платформах могут столкнуться с некоторыми проблемами при использовании команды управления reset. До этого изменения 64-битные платформы генерировали 64-битный 16-символьный дайджест в имени ограничения; например:

ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_5e8f10c132091d1e FOREIGN KEY ...

После этого изменения все платформы, независимо от размера слова, будут генерировать 32-битный 8-символьный дайджест в имени ограничения; например:

ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_32091d1e FOREIGN KEY ...

В результате этого изменения вы не сможете использовать команду управления reset на любой таблице, созданной 64-битной машиной. Это связано с тем, что новое сгенерированное имя не будет соответствовать исторически сгенерированному имени; в результате SQL, построенный командой сброса, будет недействительным.

Если вам нужно сбросить приложение, которое было создано с 64-битными ограничениями, вам нужно вручную сбросить старое ограничение перед вызовом reset.

Тестовые задания теперь выполняются в транзакции

Django 1.1 запускает тесты внутри транзакции, что позволяет повысить производительность тестов (подробнее см. test performance improvements).

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

В этих случаях вместо него можно использовать TransactionTestCase. Это просто быстрое исправление, чтобы обойти ошибки в тестовом примере, выявленные новым подходом к откату; в долгосрочной перспективе тесты должны быть переписаны, чтобы исправить тестовый пример.

Удалено промежуточное программное обеспечение SetRemoteAddrFromForwardedFor

Для удобства в Django 1.0 был включен дополнительный промежуточный класс – django.middleware.http.SetRemoteAddrFromForwardedFor – который обновлял значение REMOTE_ADDR на основе заголовка HTTP X-Forwarded-For, обычно устанавливаемого некоторыми конфигурациями прокси.

Было продемонстрировано, что этот механизм невозможно сделать достаточно надежным для использования в общем случае, и что (несмотря на документацию об обратном) его включение в Django может заставить разработчиков приложений предположить, что значение REMOTE_ADDR является «безопасным» или в некотором роде надежным источником аутентификации.

Хотя это и не является проблемой безопасности, мы решили удалить это промежуточное программное обеспечение в релизе Django 1.1. Он был заменен классом, который не делает ничего, кроме как вызывает ошибку DeprecationWarning.

Если вы полагались на это промежуточное ПО, проще всего перейти на новое:

  • Изучите the code as it existed before it was removed.
  • Проверьте, правильно ли он работает с вашим восходящим прокси-сервером, изменив его для поддержки вашего конкретного прокси-сервера (если необходимо).
  • Представьте вашу модифицированную версию SetRemoteAddrFromForwardedFor как часть промежуточного программного обеспечения в вашем собственном проекте.

Имена загруженных файлов доступны позже

В Django 1.0 файлы, загруженные и сохраненные в FileField модели, сохранялись на диск до сохранения модели в базе данных. Это означало, что фактическое имя файла, присвоенное файлу, было доступно до сохранения. Например, оно было доступно в обработчике сигнала перед сохранением модели.

В Django 1.1 файл сохраняется как часть сохранения модели в базе данных, поэтому фактическое имя файла, используемое на диске, не может быть определено до после сохранения модели.

Изменения в способе сохранения наборов форм моделей

В Django 1.1 BaseModelFormSet теперь вызывает ModelForm.save().

Это обратно несовместимо, если вы изменяли self.initial в наборе форм модели __init__, или если вы полагались на внутренние _total_form_count или _initial_form_count атрибуты BaseFormSet. Теперь эти атрибуты являются публичными методами.

Исправлено поведение экранирования фильтра join

Фильтр join больше не экранирует литеральное значение, передаваемое для коннектора.

Это обратно несовместимо для особой ситуации, когда литеральная строка содержит один из пяти специальных символов HTML. Таким образом, если вы писали {{ foo|join:"&" }}, то теперь вы должны написать {{ foo|join:"&" }}.

Предыдущее поведение было ошибкой и противоречило тому, что было документировано и ожидалось.

Постоянные перенаправления и общий вид redirect_to()

Django 1.1 добавляет аргумент permanent к представлению django.views.generic.simple.redirect_to(). Это технически обратно несовместимо, если вы использовали представление redirect_to с ключом format-string под названием „permanent“, что крайне маловероятно.

Функции, устаревшие в версии 1.1

Одна функция была помечена как устаревшая в Django 1.1:

  • Вы больше не должны использовать AdminSite.root() для регистрации админских представлений. То есть, если ваш URLconf содержит строку:

    (r'^admin/(.*)', admin.site.root),
    

    Вы должны изменить его на:

    (r'^admin/', include(admin.site.urls)),
    

Вы должны немедленно начать удалять использование этой функции из своего кода.

AdminSite.root вызовет предупреждение PendingDeprecationWarning при использовании в Django 1.1. По умолчанию это предупреждение скрыто. В Django 1.2 это предупреждение будет повышено до DeprecationWarning, которое будет громко отображаться. В Django 1.3 будет полностью удалено AdminSite.root().

Более подробную информацию о нашей политике и стратегии обесценивания см. в разделе Процесс выпуска Django.

Что нового в Django 1.1

Довольно много: с момента выхода Django 1.0 мы сделали 1 290 фиксаций кода, исправили 1 206 ошибок и добавили около 10 000 строк документации.

Основными новыми возможностями в Django 1.1 являются:

Улучшения ORM

В объектно-реляционном картографе (ORM) Django были добавлены два основных усовершенствования: поддержка агрегатов и выражений запросов.

Агрегатная поддержка

Теперь стало возможным выполнять агрегатные запросы SQL (т.е. COUNT(), MAX(), MIN() и т.д.) из ORM Django. Вы можете либо вернуть результаты агрегации напрямую, либо аннотировать объекты в QuerySet с результатами агрегатного запроса.

Эта возможность доступна в виде новых методов aggregate() и annotate(), и подробно рассматривается в the ORM aggregation documentation.

Выражения запросов

Запросы теперь могут ссылаться на другое поле в запросе и могут проходить через отношения, чтобы ссылаться на поля в связанных моделях. Это реализовано в новом объекте F; за подробной информацией, включая примеры, обратитесь к F expressions documentation.

Улучшения модели

В слой моделей Django был добавлен ряд возможностей:

«Неуправляемые» модели

Теперь вы можете контролировать, управляет ли Django жизненным циклом таблиц базы данных для модели, используя опцию managed model. По умолчанию это значение равно True, что означает, что Django создаст соответствующие таблицы базы данных в syncdb и удалит их в рамках команды reset. То есть, Django управляет жизненным циклом таблицы базы данных.

Если вы установите значение False, то для этой модели не будет автоматически создаваться или удаляться таблица базы данных. Это полезно, если модель представляет существующую таблицу или представление базы данных, которое было создано другим способом.

Более подробную информацию см. в документации к опции managed.

Прокси-модели

Теперь вы можете создавать proxy models: подклассы существующих моделей, которые добавляют только поведение на уровне Python (а не на уровне базы данных) и не представлены новой таблицей. То есть, новая модель является прокси для некоторой базовой модели, в которой хранятся все реальные данные.

Все подробности можно найти в proxy models documentation. Эта функция внешне похожа на неуправляемые модели, поэтому в документации есть объяснение how proxy models differ from unmanaged models.

Отложенные поля

В некоторых сложных ситуациях ваши модели могут содержать поля, которые могут содержать много данных (например, большие текстовые поля), или требовать дорогостоящей обработки для преобразования их в объекты Python. Если вы знаете, что вам не нужны эти конкретные поля, вы можете сказать Django не извлекать их из базы данных.

Вы сделаете это с помощью новых методов queryset defer() и only().

Улучшения при тестировании

Несколько заметных улучшений было внесено в testing framework.

Улучшение производительности тестирования

Тесты, написанные с использованием testing framework Django, теперь выполняются значительно быстрее (во многих случаях в 10 раз).

Это было достигнуто благодаря внедрению тестов на основе транзакций: при использовании django.test.TestCase ваши тесты теперь будут выполняться в транзакции, которая откатывается по завершении, вместо того, чтобы промывать и заново заполнять базу данных. Это дает значительное ускорение для большинства типов модульных тестов. Полное описание и некоторые важные замечания по поддержке базы данных см. в документации к TestCase и TransactionTestCase.

Тестирование улучшений клиента

В тестовом клиенте была сделана пара небольших - но весьма полезных - улучшений:

  • Тест Client теперь может автоматически следовать за перенаправлениями с аргументом follow в Client.get() и Client.post(). Это упрощает тестирование представлений, выдающих перенаправления.
  • Теперь получить контекст шаблона в ответе, возвращенном тестовым клиентом, стало проще: вы просто получаете доступ к контексту в виде request.context[key]. Старый способ, который рассматривает request.context как список контекстов, по одному для каждого отрисованного шаблона в цепочке наследования, все еще доступен, если вам это нужно.

Новые возможности администратора

Django 1.1 добавляет пару новых интересных функций в интерфейс администратора Django:

Редактируемые поля в списке изменений

Теперь вы можете сделать поля редактируемыми на страницах списка в админке с помощью новой опции администратора list_editable. Эти поля будут отображаться в виде виджетов форм на страницах списка, их можно редактировать и сохранять в массовом порядке.

Admin «действия»

Теперь вы можете определить admin actions, которые могут выполнять некоторые действия для группы моделей в массовом порядке. Пользователи смогут выбирать объекты на странице списка изменений, а затем применять эти массовые действия ко всем выбранным объектам.

Django поставляется с одним предопределенным действием администратора для удаления группы объектов одним махом.

Обработка условных представлений

Django теперь имеет гораздо лучшую поддержку для conditional view processing с использованием стандартных ETag и Last-Modified HTTP заголовков. Это означает, что теперь вы можете легко замыкать обработку представления, тестируя менее затратные условия. Для многих представлений это может привести к серьезному улучшению скорости и снижению пропускной способности.

Пространства имен URL

Django 1.1 улучшает named URL patterns с введением «пространств имен» URL.

Вкратце, эта возможность позволяет включать одну и ту же группу URL-адресов из одного и того же приложения в Django URLConf несколько раз, с различными (и потенциально вложенными) именованными префиксами, которые будут использоваться при выполнении обратного разрешения. Другими словами, многократно используемые приложения, такие как интерфейс администратора Django, могут быть зарегистрированы несколько раз без конфликтов URL.

Более подробную информацию можно найти в разделе the documentation on defining URL namespaces.

GeoDjango

В Django 1.1, GeoDjango (т.е. django.contrib.gis) имеет несколько новых возможностей:

  • Поддержка SpatiaLite – пространственной базы данных для SQLite – в качестве пространственного бэкенда.
  • Географические агрегаты (Collect, Extent, MakeLine, Union) и выражения F.
  • Новые методы GeoQuerySet: collect, geojson и snap_to_grid.
  • Новый список интерфейсных методов для объектов GEOSGeometry.

Более подробную информацию можно найти в документации по GeoDjango.

Другие улучшения

Другие новые возможности и изменения, введенные с версии Django 1.0, включают:

  • Класс CSRF protection middleware был разделен на два класса – CsrfViewMiddleware проверяет входящие запросы, а CsrfResponseMiddleware обрабатывает исходящие ответы. Объединенный класс CsrfMiddleware (который выполняет оба действия) остается для обратной совместимости, но теперь рекомендуется использовать разделенные классы, чтобы обеспечить тонкий контроль над тем, когда и где происходит обработка CSRF.
  • reverse() и код, который его использует (например, тег шаблона {% url %}) теперь работает с URL-адресами в административном сайте Django, при условии, что URL-адреса администратора настроены через include(admin.site.urls) (отправка запросов администратора к представлению admin.site.root по-прежнему работает, но URL-адреса в администраторе не будут «обратимыми» при такой настройке).
  • Функция include() в модулях Django URLconf теперь может принимать последовательности шаблонов URL (генерируемые patterns()) в дополнение к именам модулей.
  • Экземпляры форм Django (см. the forms overview) теперь имеют два дополнительных метода, hidden_fields() и visible_fields(), которые возвращают список скрытых - т.е. <input type="hidden"> - и видимых полей формы, соответственно.
  • Родовое представление redirect_to теперь принимает дополнительный аргумент в виде ключевого слова permanent. Если permanent равно True, представление будет выдавать постоянное перенаправление HTTP (код состояния 301). Если False, представление будет выдавать временное перенаправление HTTP (код состояния 302).
  • Новый тип поиска в базе данных – week_day – был добавлен для DateField и DateTimeField. Этот тип поиска принимает число от 1 (воскресенье) до 7 (суббота) и возвращает объекты, значение поля которых соответствует этому дню недели. Подробности см. в разделе the full list of lookup types.
  • Тег {% for %} в языке шаблонов Django теперь принимает необязательное предложение {% empty %}, которое отображается, когда {% for %} просят зациклить пустую последовательность. Примеры этого см. в the list of built-in template tags.
  • Команда управления dumpdata теперь принимает в качестве аргументов имена отдельных моделей, что позволяет экспортировать данные только из определенных моделей.
  • Есть новый фильтр шаблона safeseq, который работает так же, как safe для списков, помечая каждый элемент списка как безопасный.
  • Cache backends теперь поддерживает команды incr() и decr() для увеличения и уменьшения значения ключа кэша. На бэкендах кэша, которые поддерживают атомарное увеличение/уменьшение - в частности, на бэкенде memcached - эти операции будут атомарными и довольно быстрыми.
  • Django теперь может easily delegate authentication to the Web server через новый бэкенд аутентификации, который поддерживает стандартную переменную окружения REMOTE_USER, используемую для этой цели.
  • Появилась новая функция django.shortcuts.redirect(), которая упрощает создание перенаправлений, задавая объект, имя представления или URL.
  • Бэкенд postgresql_psycopg2 теперь поддерживает native PostgreSQL autocommit. Это продвинутая, специфическая для PostgreSQL функция, которая может значительно ускорить работу некоторых приложений с большими объемами чтения.

Что дальше?

We’ll take a short break, and then work on Django 1.2 will begin – no rest for the weary! If you’d like to help, discussion of Django development, including progress toward the 1.2 release, takes place daily on the django-developers mailing list and in the #django-dev IRC channel on irc.libera.chat. Feel free to join the discussions!

Онлайн-документация Django также содержит указания на то, как внести свой вклад в Django:

Вклад на любом уровне - разработка кода, написание документации или просто обработка заявок и помощь в тестировании предлагаемых исправлений - всегда приветствуется и ценится.

И так оно и есть.

Вернуться на верх