• 3.1
  • 3.2
  • 5.0
  • Версия документации: 6.1

О релизе Django 1.4

23 марта 2012

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

Здесь описаны `new features`_, а также `backwards incompatible changes`_ для тех, кто обновляется со старых версий. Мы удалили некоторую функциональность согласно our deprecation plan и подготовили `begun the deprecation process for some features`_.

Обзор

Самым важным изменением стало support for time zones, которая учитывает разницу даты/времени. Если эта опция включена, то Django сохраняет дату/время в формате UTC и переводит его в часовой пояс пользователя для отображения.

Если вы обновляете существующий проект до версии 1.4, перевод на новую функциональность требует осторожности: новый режим запрещает некоторое неряшливое поведение, которое было принято ранее. Мы призываем всех обратить внимание на timezone migration guide и timezone FAQ.

Другие изменения в Django 1.4:

Везде, где это возможно, мы стараемся поддерживать обратную совместимость согласно политике our API stability policy. Однако, как и предыдущие версии, Django 1.4 ломает некоторую совместимость (`backwards incompatible changes`_). Будьте осторожны при обновлении с предыдущих версий.

Совместимость версий Python

Django 1.4 более не поддерживает Python 2.4. Теперь минимальной версией является Python 2.5. Этот релиз мы протестировали на Python 2.5, 2.6, 2.7.

Это изменение должно затронуть лишь небольшое число пользователей, т.к. большинство ОС поставляется с Python 2.5 или чем-то поновее. Если у вас нет возможности уйти с Python 2.4, то лучше оставайтесь на 1.3. Согласно our support policy мы будем выпускать обновления безопасности вплоть до выпуска Django 1.5.

Django пока ещё не поддерживает Python 3.x, но в скором времени мы планируем опубликовать документ с планом перехода на Python 3.x.

Что нового в Django 1.4

Поддержка часовых поясов.

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

В Django 1.4 вы можете активировать поддержку временных зон. В этом случае дата будет записываться в базу данных в формате UTC, а используя time-zone-объекты перевод в тайм-зону пользователя будет происходить автоматически. Это может понадобиться в следующих случаях:

  • Настройка отображения даты и времени для пользователей по всему миру.

  • Сохранение даты/времени в формате UTC обеспечивает совместимость и переносимость. Это не относится к PostgreSQL, потому что это уже реализовано в Django 1.3.

  • Позволяет избежать проблем с повреждением данных при переходе DST.

Поддержка временных зон включена по умолчанию для новых проектов, созданных с помощью startproject. Если вы хотите его включить в существующем проекте, обратитесь к migration guide. При возникновении проблем загляните в FAQ.

Поддержка фреймворков для тестирования в браузере

Django 1.4 поддерживает интеграцию с фреймворками для тестирования в браузере типа Selenium. Новый класс django.test.LiveServerTestCase позволяет тестировать взаимодействие клиентской и серверной части. Подробную информацию и примеры можно найти в documentation.

Обновлён шаблон нового проекта и manage.py

Django 1.4 поставляется с обновлённым шаблоном для нового приложения, который создаётся командой startproject. Он исправляет несколько ошибок, связанных с дублирующим импортом, трудностями развертывания и прочими сложными в отладке проблемами.

Предыдущий manage.py использовал функциональность, которая стала устаревшей, так что надо бы обновить и его в проекте. Но можно пока не торопиться - он будет работать до версии 1.6, правда, в 1.5 вам напомнят исключением DeprecationWarning.

Новый рекомендуемый manage.py должен выглядеть как-то так:

#!/usr/bin/env python
import os, sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

где {{ project_name }} – имя вашего приложения.

Если настройки, пути и приложения импортируются в рамках проекта с помощью имени префикса (например, myproject.settings, ROOT_URLCONF = "myproject.urls"), то новый manage.py должен быть перемещён на директорию выше относительно settings.py и urls.py.

Например, со следующей планировкой:

manage.py
mysite/
    __init__.py
    settings.py
    urls.py
    myapp/
        __init__.py
        models.py

Вы должны импортировать mysite.settings, mysite.urls, mysite.myapp, а не settings, urls, myapp в виде модулей верхнего уровня.

Все, что импортировано как модуль верхнего уровня, может быть размещено рядом с новым файлом «manage.py». Например, чтобы отделить myapp от модуля проекта и импортировать его как просто myapp, поместите его вне каталога mysite/:

manage.py
myapp/
    __init__.py
    models.py
mysite/
    __init__.py
    settings.py
    urls.py

Если же импорт идёт непоследовательно (где-то с префиксом проекта, где-то без), то его необходимо почистить при обновлении manage.py.

Пользовательские проекты и шаблоны приложений

Команды startapp и startproject теперь имеют опцию --template для указания пути или URL до пользовательского приложения или шаблона.

Например, Django будет использовать каталог /path/to/my_project_template, когда вы запускаете следующую команду:

django-admin.py startproject --template=/path/to/my_project_template myproject

Вы также можете теперь указать каталог назначения в качестве второго аргумента как для startapp, так и для startproject:

django-admin.py startapp myapp /path/to/new/app
django-admin.py startproject myproject /path/to/new/project

За подробностями обратитесь к startapp и startproject.

Улучшение поддержки WSGI

Команда startproject теперь добавляет в новый проект файл wsgi.py, содержащий простое приложение WSGI, которое используется deploying with WSGI app servers.

built-in development server теперь поддерживает внешние определения вызовов WSGI, что даёт возможность запустить runserver с конфигурацией на боевом сервере. Новая настройка WSGI_APPLICATION определяет какие вызовы WSGI использует runserver.

(Команда runfcgi является обёрткой для WSGI, настроенной с помощью WSGI_APPLICATION.)

Поддержка SELECT FOR UPDATE

В Django 1.4 есть метод QuerySet.select_for_update(), который генерирует SQL запрос SELECT ... FOR UPDATE. Это блокирует записи до окончания транзакции, так что остальные пользователи не смогут их изменить или удалить.

За подробностями обратитесь к select_for_update().

Model.objects.bulk_create в ORM

Этот метод позволяет создавать несколько объектов более эффективно. Это может привести к значительному увеличению производительности, если у вас много объектов.

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

Подробнее описано в bulk_create().

Улучшенное хеширование паролей

Система аутентификации Django (django.contrib.auth) хранит пароли с односторонним алгоритмом шифрования. Django 1.3 использует SHA1, однако с ростом производительности компьютеров риск успешной атаки всё повышается. В Django 1.4 представлена новая система хранения паролей, основанная на алгоритме PBKDF2 (рекомендован NIST). Тем не менее вы можете указать свой, например, популярный bcrypt. Для подробностей смотрите в Как Django хранит пароли.

Поддержка HTML5

В админке и прочих стандартных шаблонах мы теперь используем тип документа HTML5. В то же время Django старается сохранить совместимость со старыми браузерами. Это изменение позволяет использовать возможности HTML5 без потери корректности HTML, а также указать самому тип документа.

Фильтрация списков в интерфейса администратора

До Django 1.4 admin позволяло указывать значения отдельных полей без возможности создания своих фильтров. Это было исправлено с помощью небольшого API (ранее использовался внутренний «FilterSpec»). Подробнее можно прочитать здесь list_filter.

Множественная сортировка в интерфейсе администратора

Теперь в админке можно указывать сортировку по нескольким столбцам. Учитываются все элементы, указанные в атрибуте ordering. Поведение взято из настольного GUI - достаточно кликнуть по заголовку столбца. Мы также добавили метод get_ordering() для указания сортировки динамически, например, в зависимости от запроса.

Новые методы в ModelAdmin

Мы добавили метод save_related() в модель ModelAdmin для возможности управления сохранением связанных объектов.

Два других новых метода класса ModelAdmin get_list_display() и get_list_display_links() включают динамическое управление полями и ссылками, которые будут показаны в таблицах админки.

Проверка прав в панели администратора

В админке теперь доступны только те действия, на которые пользователь имеет разрешения. Для отношения ManyToMany, когда создаётся модель, на которую пользователь не имеет явных прав, они определяются из прав на отношение.

Инструменты для криптографических подписей

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

Подробнее можно посмотреть здесь cryptographic signing.

Новый FormWizard

Предыдущий FormWizard из модуля django.contrib.formtools заменён новой реализацией, основанной на классах представлений, которые появились в Django 1.3. Вместе с тем стало возможным подключить API для хранения, чтобы передавать скрытые поля с предыдущего шага.

Django 1.4 поставляется с возможностью хранения информации пользователя в сессиях или куках. Последние имеют инструменты для cryptographic signing, которые введены в Django 1.4 для хранения состояния помощника (wizard`а) в куках.

reverse_lazy

Ленивая версия вычисления django.core.urlresolvers.reverse() была добавлена для расшифровки URL до загрузки URLconf.

Трансляция шаблонов URL

С помощью функции хэлпера i18n_patterns() Django теперь может учитывать языковой префикс в URL. Благодаря ugettext_lazy() стало возможным определять URL для интернационализации. Смотри Интернационализация: в шаблонах URL для информации об использовании языковых префиксов и интернационализации шаблонов URL.

Поддержка контекстного перевода для {% trans %} и {% blocktrans %}

Поддержка contextual translation была введена в Django 1.3 с помощью функции pgettext, которая расширяла теги trans и blocktrans через ключевое слово context.

Настройка SingleObjectMixin URLConf kwargs

Два новых атрибута pk_url_kwarg и slug_url_kwarg были добавлены в класс SingleObjectMixin для возможности настройки URLconf через единственный общий объект представления.

Связывание тегов шаблонизатора

Новая функция assignment_tag была добавлена в template.Library для упрощения создания тегов, которые хранят данные в контекстной переменной.

Поддержка *args и **kwargs для хэлперов тегов

Хэлперы шаблонов simple_tag, inclusion_tag и новый assignment_tag теперь может принимать позиционные или словарные параметры:

@register.simple_tag
def my_tag(a, b, *args, **kwargs):
    warning = kwargs["warning"]
    profile = kwargs["profile"]
    ...
    return ...

Тогда в шаблоне любое число аргументов может быть передано в тег:

{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}

Обёртывание исключений в режиме TEMPLATE_DEBUG

В предыдущей версии Django в случае, когда TEMPLATE_DEBUG установлена в True, любое исключение при рендеринге шаблонов (даже не связанное с синтаксисом шаблона) порождало вызов исключения TemplateSyntaxError. Это было сделано в целях получения детальной информации для отладочной страницы ошибки 500.

В Django 1.4 исключения не перехватываются. Вместо этого оригинальное исключение дополняется информацией об источнике. Это означает, что теперь можно ловить исключения при рендеринге шаблонов вне зависимости от значения TEMPLATE_DEBUG, и нет необходимости ловить и разворачивать TemplateSyntaxError для обработки остальных ошибок.

Фильтр шаблона truncatechars

Новый фильтр урезает строку до определённого количества символов. Обрезанная строка заканчивается последовательностью «…». Подробнее в документации по truncatechars.

Тег шаблона static

Приложение staticfiles имеет новый тег шаблона static для ссылки на файлы, сохраненные в хранилище STATICFILES_STORAGE. Он использует метод url серверной части хранилища и, следовательно, поддерживает расширенные функции, такие как:ref:обслуживание файлов из облачной службы<staticfiles-from-cdn>.

Поддержка бэкенда CachedStaticFilesStorage

В модуль staticfiles добавлен класс бэкенда CachedStaticFilesStorage, который кэширует файлы при сохранении (при запуске команды collectstatic), добавляя MD5 к имени файла. Например, файл css/styles.css будет сохранён как css/styles.55e7cbb9ba48.css.

Простая защита от кликджекинга

Мы добавили поддержку защиты от clickjacking, который использует атрибут заголовка X-Frame-Options. Из-за обратной совместимости она отключена по умолчанию; как её включить можно посмотреть в enable it, чтобы обезопасить пользователей браузеров, которые поддерживают этот заголовок.

Улучшение CSRF

Мы проделали некоторые улучшения в плане поддержки CSRF, включая декоратор ensure_csrf_cookie(), который будет полезен в тяжёлых AJAX-сайтах; защита запросов PUT и DELETE; настройки CSRF_COOKIE_SECURE и CSRF_COOKIE_PATH, которые обеспечивают большую защиту от CSRF-атак. Подробнее можно посмотреть в разделе CSRF docs.

Фильтрации отчётов об ошибках

Мы добавили два декоратора функций (sensitive_variables() и sensitive_post_parameters()) для обработки переменных и POST-параметров с целью исключения какой-либо персонализированной информации из отчётов об ошибках.

Все POST-параметры теперь постоянно фильтруют вывод отчёта для определённых представлений (login, password_reset_confirm, password_change и add_view в модуле django.contrib.auth.views, известном также как user_change_password в админке) для предотвращения утечки информации, например, паролей.

Вы можете перекрыть поведение по умолчанию, написав свой фильтр custom filter. Подробнее можно прочитать в Filtering error reports.

Расширена поддержка IPv6

В Django 1.4 улучшена поддержка IPv6 с помощью нового класса поля модели GenericIPAddressField, поля формы GenericIPAddressField и валидаторов validate_ipv46_address и validate_ipv6_address.

Сравнение HTML в тестах

В базовый класс тестов django.test добавлены хелперы для нестрого сравнения HTML, исключающие несовпадение пробелов, кавычки аргументов, их порядок. Вы можете сравнить непосредственно два HTML-документа через новые методы assertHTMLEqual() и assertHTMLNotEqual() или использовать флаг html=True в методе assertContains() и assertNotContains() для проверки что же отдаётся клиенту. Смотрите документацию по assertions documentation.

Два новых формата даты

Два новых формата date добавлены в фильтры шаблонов, тегов и format-localization:

  • e – название временной зоны у объекта даты/времени

  • o – номер года по ISO 8601

Если вы используете e или o, обновитесь согласно custom format files. Например, для локализации на испанский экранируйте аналогично d:

DATE_FORMAT = r"j \de F \de Y"

Теперь же нужно экранировать и e с o:

DATE_FORMAT = r"j \d\e F \d\e Y"

Подробнее можно посмотреть в документации к date.

Минорные изменения

Django 1.4 включает в себя также несколько небольших изменений:

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

  • Tablespace support в PostgreSQL.

  • Настраиваемые имена для simple_tag().

  • Посмотрите раздел security overview в документации.

  • Функция django.contrib.auth.models.check_password перемещена в модуль django.contrib.auth.hashers. Старый импорт всё ещё работает, но рекомендуется его обновить.

  • Команда collectstatic обзавелась опцией --clear, при указании которой перед копированием все старые файлы будут удалены.

  • Стало возможным использовать для MySQL/InnoDB фикстуры со сложными зависимостями.

  • Новый обработчик ошибки 403 добавлен как 'django.views.defaults.permission_denied'. Вы можете указать свой обработчик в django.conf.urls.handler403. Подробнее можно посмотреть в документации по the 403 (HTTP Forbidden) view.

  • Команда makemessages использует новый и более точный лексер JsLex для извлечения переводимых строк из файлов JavaScript.

  • Тег шаблонизатора trans теперь принимает опциональный аргумент as, чтобы получить строку перевода без её отображения, а вместо этого настроить какую-либо контекстную переменную.

  • Тег шаблонизатора if теперь поддерживает {% elif %}.

  • Если вы используете Django за прокси, то вам может пригодиться новая настройка SECURE_PROXY_SSL_HEADER. Она решает проблему, когда прокси отбрасывает тот факт, что запрос пришёл через HTTPS. Используёте её только когда точно понимаете, что вы делаете.

  • Новая текстовая версия страницы внутренней ошибки кода состояния HTTP 500, обслуживаемая, когда DEBUG имеет значение True, теперь отправляется клиенту, когда Django обнаруживает, что запрос возник в коде JavaScript. (Для этого используется is_ajax().)

    Как и в случае HTML, там будет содержаться ряд полезной информации о состоянии приложения.

    Это должно помочь при отладке взаимодействия клиентского JavaScript и серверной части.

  • Добавлен параметр makemessages --no-location.

  • Вместо бэкенда кэша locmem следует использовать pickle.HIGHEST_PROTOCOL для лучшей совместимости с остальными кэширующими бэкендами.

  • В ORM добавлена поддержка DISTINCT ON для запросов SELECT.

    Метод distinct() у QuerySet теперь может опционально принимать список полей модели. Если он указан, то выражение DISTINCT действует только на эти поля. Поддерживается пока только в PostgreSQL.

    Подробнее в документации distinct().

  • Страница входа администратора добавит ссылку для сброса пароля, если вы включите URL-адрес с именем «admin_password_reset» в свой «urls.py», поэтому подключить встроенный механизм сброса пароля и сделать его доступным теперь намного проще. Подробнее см. Добавление возможности сброса пароля.

  • В поддержку MySQL добавлена функциональность по работе с точками сохранения, которые были реализованы в версии 5.0.3 для движка InnoDB.

  • Стало возможным передавать начальные значение в форму модели, которая представляет из себя набор форм, построенных с помощью modelformset_factory или inlineformset_factory. Тем не менее, начальные значения применяются только к дополнительным формам, то есть те, которые не связаны с существующего экземпляра модели.

  • В поддержку карты сайта добавлена возможность работы с HTTPS-ссылками, которая реализована с помощью атрибута Sitemap.protocol.

  • Новый класс django.test.SimpleTestCase, потомок unittest.TestCase, который легче, чем django.test.TestCase и прочие. Его следует применять, когда не требуется подключение к БД, подробнее в Иерархия классов для тестов в Django.

Обратная несовместимость в 1.4

SECRET_KEY теперь обязателен

Работа сайта с пустой или известной злоумышленнику настройкой SECRET_KEY сразу нивелирует многие средства защиты вплоть до выполнения чужого кода. Ни один сайт на Django не должен запускаться без этой настройки.

В Django 1.4 запуск Django с пустым SECRET_KEY вызовет предупреждение DeprecationWarning. В Django 1.5 возникнет исключение, и Django откажется запускаться. Это немного ускоряется по сравнению с обычным путем устаревания из-за серьезных последствий запуска Django без SECRET_KEY.

django.contrib.admin

Включаемое по умолчанию приложение django.contrib.admin долгое время поставлялось с набором статики: JavaScript, CSS, картинки… В Django 1.3 Добавлено новое приложение django.contrib.staticfiles для обработки этих файлов в общем виде и определения соглашений для всех включённых приложений.

Начиная с Django 1.4, статические файлы администратора также следуют этому соглашению, чтобы упростить развертывание файлов. В предыдущих версиях Django также было принято определять параметр ADMIN_MEDIA_PREFIX, чтобы указать URL-адрес, по которому на веб-сервере находятся статические файлы администратора. Этот параметр устарел и заменен более общим параметром STATIC_URL. Теперь Django будет ожидать найти статические файлы администратора по URL <STATIC_URL>/admin/.

Если вы ранее использовали URL-путь для ADMIN_MEDIA_PREFIX (например, /media/), просто убедитесь, что STATIC_URL и STATIC_ROOT настроены и ваш веб-сервер правильно обслуживает эти файлы. Сервер разработки продолжает обслуживать файлы администратора, как и раньше. Для получения более подробной информации прочтите статические файлы с практическими рекомендациями.

Если ADMIN_MEDIA_PREFIX указывает на какой-либо домен (например, http://media.example.com/admin/), убедитесь, что в STATIC_URL правильный путь – например, http://media.example.com/.

Предупреждение

Если вы использовали знание внутреннего расположения файлов статики для админки, то вам нужно обновить пути: эти объекты были перемещены из django/contrib/admin/media/ в django/contrib/admin/static/admin/.

Поддерживаемые браузеры для админки

Django не следует какой-либо чёткой политике поддержки браузеров в админке. На практике же это сводится к следующему: браузеры из YUI’s A-grade должны поддерживаться полностью, за исключением IE 6, который снят с поддержки.

Выпущенный более 10 лет назад, IE6 накладывает множество ограничений на современную веб-разработку. Практические последствия этой политики заключаются в том, что участники могут улучшать администратора без учета этих ограничений.

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

Иконки для админки

В рамках улучшения быстродействия и юзабилити админки иконки виджетов для фильтров horizontal и vertical были перемещены и сгруппированы в два файла класса.

А именно: selector-add.gif, selector-addall.gif, selector-remove.gif, selector-removeall.gif, selector_stacked-add.gif и selector_stacked-remove.gif слиты в selector-icons.gif; arrow-up.gif и arrow-down.gif в sorting-icons.gif.

Если вы использовали эти файлы для модификации админки, вам нужно заменить их своими или взять из предыдущей версии.

Имена классов CSS в панели администратора

Дабы избежать конфликтов с остальными именами классов CSS (например, «button»), мы добавили префикс («field-») ко всем иенам классов, которые генерируются автоматически из имён полей формы, встраиваемых форм и ячеек таблиц. Адаптируйте ваши таблицы стилей и JavaScript код для учёта этого факта.

Совместимость с ранее подписанными данными

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

Так что, если вы обновляетесь до 1.4 с версии 1.2 или меньшей, вы можете потерять некоторые части данных, которые были подписаны с помощью старого криптографического метода. В данном случае рекомендуется какое-то время использовать Django 1.3, чтобы срок хранения подписанных данных истёк, и они бы шифровались новым алгоритмом. Подверженные этой проблеме данные описаны ниже, где 1) последствия при игнорировании рекомендации 2) время, необходимое для новой подписи данных.

  • проверка целостности данных в contrib.sessions

    • Последствия: Пользователь будет разлогинен, и данные сессии потеряются.

    • Срок перевалидации: Определён в SESSION_COOKIE_AGE.

  • Хеш восстановления пароля в contrib.auth

    • Последствия: Старые ссылки для восстановления пароля перестанут работать.

    • Период времени: определяется PASSWORD_RESET_TIMEOUT_DAYS.

Хеши для форм: они имеют очень короткое время жизни. Так что это актуально только когда пользователь заполняет форму, сгенерированную Django до обновления, а отправляет уже в обновлённую версию:

  • Хеш безопасности contrib.comments

    • Последствия: Пользователь увидит ошибку валидации «Security hash failed.»

    • Срок перевалидации: Всё время, пока пользователь пишет комментарий.

  • Хеш безопасности FormWizard

    • Последствия: Пользователь увидит сообщение об ошибке, в которой сказано, что он будет перенаправлен к первой форме мастера с потерей всех введённых данных.

    • Срок перевалидации: Всё время, пока пользователь заполняет форму.

  • Проверка CSRF

    • Замечание: Это актуально для совместимости с Django 1.1 (не Django 1.2), и имеет значение только при обновлении с версии 1.1.

    • Последствия: Пользователь увидит ошибку 403 с сообщением о том, что сработала CSRF-защита.

    • Срок перевалидации: Всё время, пока пользователь заполняет форму.

  • Обновление паролей пользователей через contrib.auth

    • Последствия: При записи в БД пароль пользователя будет обновлён с помощью нового криптостойкого алгоритма. Так что если вы обновитесь до 1.4, а потом откатитесь на 1.3, некоторые пользователи не смогут войти.

    • Лекарство: Установите PASSWORD_HASHERS

django.contrib.flatpages

Начиная с версии 1.4 класс FlatpageFallbackMiddleware только добавляет конечный слэш и перенаправляет на получившийся URL, если такая страница есть в приложении. Например, при запросе /notaflatpageoravalidurl в предыдущей версии шло перенаправление на /notaflatpageoravalidurl/, что порождало исключение, теперь же уже /notaflatpageoravalidurl будет вызывать ошибку 404.

К тому же перенаправление таким образом считается перманентным (с кодом 301) в соответствии с поведением класса CommonMiddleware.

Сериализация datetime и time

В следствии поддержки часовых поясов и согласно спецификации ECMA-262, мы внесли изменения в сериализатор JSON:

  • Для datetime-объектов добавляется временная зона, в случае с time-объектами генерируется исключение.

  • Для datetime- и time-объектов добавлена поддержка миллисекунд. Немного теряется точность, потому что Python хранит микросекунды (6 знаков), а JSON миллисекунды (3 знака). Однако, это всё равно лучше, чем простое их игнорирование в предыдущих версиях.

Мы добавили в XML-сериализатор поддержку формата ISO8601 для даты со временем. Для разделения части даты от части времени используется буква T вместо пробела. Информация по временной зоне включает в себя формат [+-]HH:MM.

Хотя сериализаторы теперь используют новые форматы при создании фикстур, они все еще могут загрузить фикстуры, созданные ранее.

Для SQLite supports_timezone установлен в False

Для SQLite поддержка временных зон может быть включена, однако, если вы сохраняете datetime-объект, SQLite представляет его как строку с указанием UTC. При загрузке же из базы эта информация отбрасывается, что может привести к порче данных.

В контексте поддержки временных зон этот флаг изменён на False, и дата-время сохраняется без этой информации. Когда настройка USE_TZ установлена в False, при попытке сохранения со сведениями UTC произойдёт исключение.

Специфические исключения MySQLdb

Исторически MySQL-бэкенд вызывал MySQLdb.OperationalError, если в запросе происходило исключение. Мы исправили этот баг, теперь вызывается django.db.DatabaseError. Если у вас были завязки на MySQLdb.OperationalError, адаптируйте блок except.

Потокобезопасные соединения с БД

Объекты DatabaseWrapper (включая соединения типа django.db.connection и django.db.connections["что_то_там"]) потокобезопасны. Сейчас они представляют из себя глобальные объекты, дабы имелся доступ из разных потоков. В то время как собственно объекты соединений глобальны, словарь django.db.connections остаётся потокобезопасным. Однако, если вы используете ORM или DatabaseWrapper.cursor(), то заметите некоторое изменение в поведении. Теперь django.db.connection не ссылается напрямую на DatabaseWrapper, а использует прокси для доступа к атрибутам объекта. Если вам всё-таки нужен непосредственно текущий DatabaseWrapper, используйте django.db.connections[DEFAULT_DB_ALIAS].

В рамках этого изменения все базовые соединения SQLite теперь включены для потенциального совместного использования потоков (путем передачи атрибута check_same_thread=False в pysqlite). Однако DatabaseWrapper сохраняет предыдущее поведение, отключив совместное использование потоков по умолчанию, поэтому это не влияет на какой-либо существующий код, который полностью полагается на ORM или на DatabaseWrapper.cursor().

Наконец, т.к. стало возможным передавать соединения между потоками, Django не предпринимает никаких усилий для организации синхронизации с основным бэкендом. Параллельное поведение определяется базовой реализацией бэкендов. Загляните в документацию для выяснения подробностей.

Настройка COMMENTS_BANNED_USERS_GROUP

Django comments app исторически поддерживал исключение комментариев для определённой группы пользователей, однако мы нигде не освещали этот момент и не применяли это исключение в других частях приложения, например, в тегах шаблонов. Для решения проблемы мы просто исключили этот код.

Если вам всё-таки нужно старое поведение, используйте свой менеджер моделей для исключения групп пользователей, например:

from django.conf import settings
from django.contrib.comments.managers import CommentManager


class BanningCommentManager(CommentManager):
    def get_query_set(self):
        qs = super().get_query_set()
        if getattr(settings, "COMMENTS_BANNED_USERS_GROUP", None):
            where = [
                "user_id NOT IN (SELECT user_id FROM auth_user_groups WHERE group_id = %s)"
            ]
            params = [settings.COMMENTS_BANNED_USERS_GROUP]
            qs = qs.extra(where=where, params=params)
        return qs

Сохраните этот менеджер моделей в вашем приложении для комментариев (например, в my_comments_app/managers.py) и добавьте в ваш custom comment app model:

from django.db import models
from django.contrib.comments.models import Comment

from my_comments_app.managers import BanningCommentManager


class CommentWithTitle(Comment):
    title = models.CharField(max_length=300)

    objects = BanningCommentManager()

Настройки IGNORABLE_404_STARTS и IGNORABLE_404_ENDS

До Django 1.4 было возможным исключить из обработки некоторые URL (404 error reporting) путём добавления префикса в IGNORABLE_404_STARTS и суффикса в IGNORABLE_404_ENDS.

Теперь же обе эти настройки переместились в IGNORABLE_404_URLS, в котором хранится список скомпилированных регулярных выражений. Django не будет генерировать ошибку 404 для любого из них.

Однако, IGNORABLE_404_STARTS и IGNORABLE_404_ENDS имели настройки по умолчанию:

IGNORABLE_404_STARTS = ("/cgi-bin/", "/_vti_bin", "/_vti_inf")
IGNORABLE_404_ENDS = (
    "mail.pl",
    "mailform.pl",
    "mail.cgi",
    "mailform.cgi",
    "favicon.ico",
    ".php",
)

Django не будет определять остались ли у вас всякие /cgi-bin/ или favicon.ico.Теперь по умолчанию списки IGNORABLE_404_URLS, IGNORABLE_404_STARTS и IGNORABLE_404_ENDS пусты.

Если вы настраивали IGNORABLE_404_STARTS или IGNORABLE_404_ENDS, или если хотите сохранить старое поведение по умолчанию, добавьте в файл настроек следующие строки:

import re

IGNORABLE_404_URLS = (
    # for each <prefix> in IGNORABLE_404_STARTS
    re.compile(r"^<prefix>"),
    # for each <suffix> in IGNORABLE_404_ENDS
    re.compile(r"<suffix>$"),
)

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

CSRF-защита распространена на запросы PUT и DELETE

Изначально Django поддерживал защиту от CSRF только для POST-запросов, как это описано в CSRF protection. Однако, сейчас стало популярным использовать в AJAX-запросах PUT и DELETE, так что мы решили следовать RFC 2616 – включая GET, HEAD, OPTIONS и TRACE и включить защиту для всех запросов.

Если вы используете методы PUT или DELETE в AJAX-приложениях, изучите instructions about using AJAX and CSRF.

Представление сброса пароля теперь принимает subject_template_name

Представление password_reset в django.contrib.auth теперь принимает параметр subject_template_name, который передаёт форму пароля как аргумент. Если вы используете это представление со своей формой сброса пароля, то убедитесь, что метод save() принимает этот аргумент.

django.core.template_loaders

Начиная с 2005 года это была ссылка на django.template.loader, и теперь мы наконец-то удалили её. Замените в коде django.core.template_loaders на django.template.loader.

django.db.models.fields.URLField.verify_exists

Эта функциональность была удалена в следствии ошибок безопасности и падения производительности. Все вызовы verify_exists должны быть удалены.

django.core.files.storage.Storage.open

Метод open базового класса Storage принимал непонятный параметр mixin, который позволял динамически менять класс возвращаемого файлового объекта. Теперь он удалён. В тех редких случаях, когда он всё же использовался, вы можете адаптировать код, переопределив метод open:

from django.core.files import File
from django.core.files.storage import FileSystemStorage


class Spam(File):
    """
    Spam, spam, spam, spam and spam.
    """

    def ham(self):
        return "eggs"


class SpamStorage(FileSystemStorage):
    """
    A custom file storage backend.
    """

    def open(self, name, mode="rb"):
        return Spam(open(self.path(name), mode))

Десериализатор YAML теперь использует yaml.safe_load

yaml.load может построить любой объект Python, который может выполнить любой код из ненадёжного источника. Это функция не нужна непосредственно десериализатору YAML для Django, которой использует загрузку фикстур только примитивных объектов. Так что для обеспечения безопасности теперь используется yaml.safe_load.

По умолчанию сессионные куки имеют флаг httponly

Сеансовые файлы cookie теперь по умолчанию включают атрибут httponly, чтобы снизить влияние потенциальных XSS-атак. В результате этого изменения данные сеансовых файлов cookie, включая sessionid, больше не доступны из JavaScript во многих браузерах. Для строгой обратной совместимости используйте SESSION_COOKIE_HTTPONLY = False в вашем файле настроек.

Фильтр urlize более не экранирует каждый URL

Если URL содержит %xx, где xx - числа, то urlize понимает, что этот URL уже экранирован и не пытается проделать это ещё раз. Такое поведение неверно для URL, которые содержат последовательность %xx, но вряд ли они появятся в реальном окружении, к тому же браузеры не смогут правильно понять куда же им идти.

assertTemplateUsed и assertTemplateNotUsed как менеджеры контекстов

Теперь стало возможным проверить используется ли шаблон в блоке кода с помощью методов assertTemplateUsed() и assertTemplateNotUsed(). Эти методы можно использовать как менеджеры контекстов:

with self.assertTemplateUsed("index.html"):
    render_to_string("index.html")
with self.assertTemplateNotUsed("base.html"):
    render_to_string("index.html")

Подробнее здесь assertion documentation.

Соединения к БД после запуска тестов

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

Если в коде у вас были завязки на это, то вы можете восстановить прежнее поведение перекрыв метод teardown_databases() у DjangoTestRunner.

Вывод manage.py help

manage.py help теперь группирует доступные команды по приложениям. Если вы зависели от этого вывода – например, парсили его – адаптируйте свой код. Получить список всех доступных команд можно с помощью manage.py help --commands.

Тег шаблона extends

Ранее тег extends использовал примитивный алгоритм разбора аргументов, ошибочно считая строкой то, что по сути не было ею. Теперь же parser.compile_filter работает также, как и остальные теги.

Внутренности этого тега не были частью публичного API, но в интересах реализации ExtendsNode.__init__ изменилось, что может сказаться на совместимости с тегами, основанными на этом классе.

Загрузка неполных фикстур более не поддерживается

До версии 1.4 для полей даты и времени в модели можно было указать значения auto_now и auto_now_add при загрузке фикстур. Это работало не всегда так, как хотелось, и в 1.4 было решено убрать такую возможность, потому что фикстуры загружались в «сыром» виде, вне зависимости от опций модели.

Многопоточность встроенного сервера

Сервер разработки теперь по умолчанию является многопоточным. Используйте параметр runserver --nothreading, чтобы отключить использование потоков на сервере разработки:

django-admin.py runserver --nothreading

Отключены атрибуты в разметке при активации безопасного режима

До Django 1.4 атрибуты были включены в вывод разметки вне зависимости от настроек безопасности фильтра. В версии 2.1 в библиотеку Python-Markdown была добавлена опция enable_attributes. При установке safe_mode=True и enable_attributes=False в фильтр будут передаваться безопасные аргументы. Использование версии Python-Markdown < 2.1, приведёт к предупреждению безопасности.

get_initial у FormMixin возвращает изначальный словарь

В Django 1.3 метод get_initial класса django.views.generic.edit.FormMixin возвращал класс initial словаря. Мы решили возвращать копию словаря, так как экземпляры форм могли модифицировать исходные данные без изменения переменной класса.

Устаревшая функциональность в 1.4

Старый стиль вызова декоратора cache_page

Некоторые вызовы cache_page() стали устаревшими. Обратитесь к документации для правильного использования этого декоратора.

Поддержка версий PostgreSQL меньше 8.2

Django 1.3 не работает с PostgreSQL младше 8.0, и мы настоятельно рекомендуем использовать более новые версии, тем более что срок окончания поддержки 8.0 и 8.1 уже близок (ноябрь 2010).

В Django 1.4 мы учли это и сделали версию 8.2 минимально поддерживаемой.

Исключения в запросе теперь всегда логгируются

После того как мы добавили logging support в Django 1.3, оповещение администратора по email было перемещено в класс django.utils.log.AdminEmailHandler, который прикреплялся к логгеру django.request. В целях совместимости с предыдущим поведением логгер django.request будет вызван только если DEBUG установлен в False.

Для увеличения гибкости регистрации ошибок запросов логгер 'django.request' сейчас вызывается независимо от значения DEBUG, однако в новом проекте по умолчанию добавлен фильтр в django.utils.log.AdminEmailHandler для предотвращения отправки сообщений об ошибках в режиме разработки:

LOGGING = {
    # ...
    "filters": {
        "require_debug_false": {
            "()": "django.utils.log.RequireDebugFalse",
        }
    },
    "handlers": {
        "mail_admins": {
            "level": "ERROR",
            "filters": ["require_debug_false"],
            "class": "django.utils.log.AdminEmailHandler",
        }
    },
}

Если вы адаптируете уже существующий проект, то в настройке LOGGING этого фильтра нет. Для обратной совместимости Django определит, что у вашего обработчика 'mail_admins' нет раздела 'filters' и автоматически добавит его. В Django 1.5 мы будем выводить предупреждение, а в версии 1.6 эта совместимость будет удалена.

Добавление ключа 'filters' в обработчик 'mail_admins' рушит обратную совместимость.

django.conf.urls.defaults

Вплоть до Django 1.3 функции include(), patterns() и url(), а также handler404, handler500 располагались в модуле django.conf.urls.defaults.

В Django 1.4 они перемещены в модуль django.conf.urls.

django.contrib.databrowse

Просмотрщик данных долгое время не развивался, и по сей день не было новых коммитов. Было предложено GSOC project интегрировать в панель администратора, но никакого прогресса не видно. В то время как Databrowse стал устаревшим, некоторая его функциональность переместилась в django.contrib.admin.

Лицензия на Databrowse совпадает с лицензией Django, так что любой желающий может доработать его для себя.

django.core.management.setup_environ

Эта функция временно модифицирует sys.path, делая возможным импорт каталога проекта для старой структуры проекта, создаваемой startproject. Эта функция более не нужна с новым manage.py и структурой проекта.

Эта функция никогда не документировалась и не была частью общедоступного API, но ее широко рекомендовали для использования при настройке «среды Django» для пользовательского сценария. Такое использование следует заменить установкой переменной среды DJANGO_SETTINGS_MODULE или использованием django.conf.settings.configure().

django.core.management.execute_manager

Эта функция ранее использовалась manage.py для выполнения команд приложения.Она идентична django.core.management.execute_from_command_line за исключением первого вызова setup_environ. Так что теперь объявлена устаревшей, вместо неё следует использовать execute_from_command_line. Ни одна из этих функций не документирована в рамках API, но объявить устаревшей django.core.management.execute_manager всё-таки нужно для дальнейшего использования manage.py.

Атрибуты фильтров в шаблонах needs_autoescape и is_safe

Два флага (is_safe и needs_autoescape) определяют как каждый фильтр шаблона взаимодействует с автоэкранированием Django. Раньше они были атрибутами функции:

@register.filter
def noop(value):
    return value


noop.is_safe = True

Однако, это вызывало проблемы при комбинировании декораторов, особенно @stringfilter. Теперь же флаги являются аргументами @register.filter:

@register.filter(is_safe=True)
def noop(value):
    return value

Подробнее в документации filters and auto-escaping.

Расширение имен приложений подстановочными знаками в INSTALLED_APPS

До Django 1.3 INSTALLED_APPS позволяло использовать маску в именах приложения, например, django.contrib.*. Расшифровка была возможна за счёт реализации from <package> import *, основанной на структуре файлов. К сожалению, `this can't be done reliably`_.

Такое поведение никогда не было задокументировано. Поскольку он не является Python, он был удален в Django 1.4. Если вы полагались на него, вам необходимо отредактировать файл настроек, чтобы в явном виде перечислить все ваши приложения.

HttpRequest.raw_post_data переименован в HttpRequest.body

Этот атрибут назывался HttpRequest.raw_post_data, но на самом деле представлял собой тело HTTP запроса. Теперь он объявлен устаревшим, а вместо него следует использовать HttpRequest.body.

Исправлена потенциальная ошибка производительности в django.contrib.sitemaps

В предыдущих версиях объекты Paginator, используемые в классах карты сайта, кэшировались, что могло привести к устареванию карт сайта. Мы удалили кэширование, поэтому каждый запрос к карте сайта теперь создает новый объект Paginator и вызывает метод items подкласса Sitemap. В зависимости от того, что делает ваш метод item(), это может отрицательно сказаться на производительности. Чтобы смягчить влияние на производительность, рассмотрите возможность использования инфраструктуры кэширования в вашем подклассе Sitemap.

Версии Python-Markdown меньшие 2.1

Версии Python-Markdown меньшие, чем 2,1 не поддерживают возможность отключения атрибутов. В целях безопасности старые версии этой библиотеки не будут поддерживаться для разметки в 1.5 и подлежат скорейшему отключению.

Back to Top