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

23 марта 2012

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

Эти заметки о выпуске охватывают new features, а также некоторые backwards incompatible changes, о которых вы должны знать при переходе с Django 1.3 или более старых версий. Мы также отказались от некоторых функций, которые подробно описаны в our deprecation plan, и мы begun the deprecation process for some features.

Обзор

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

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

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

По мере возможности мы стараемся внедрять новые возможности с обратной совместимостью в соответствии с политикой our API stability policy. Однако, как и в предыдущих релизах, Django 1.4 поставляется с некоторыми незначительными backwards incompatible changes; людям, переходящим с предыдущих версий Django, следует внимательно ознакомиться с этим списком.

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

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

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

В настоящее время Django не поддерживает Python 3.x. В какой-то момент до выхода Django 1.4 мы планируем опубликовать документ, описывающий наши полные сроки отказа от Python 2.x и перехода на Python 3.x.

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

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

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

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

  • Настройка отображения даты и времени для пользователей по всему миру.
  • Хранение временных меток в UTC для переносимости и совместимости баз данных. (Этот аргумент не относится к PostgreSQL, потому что он уже хранит временные метки с информацией о часовом поясе в Django 1.3).
  • Избежание проблем с повреждением данных при переходе на летнее время.

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

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

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

Обновлен макет проекта по умолчанию и manage.py.

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

Предыдущий manage.py вызывал функции, которые сейчас устарели, и поэтому проекты, переходящие на Django 1.4, должны обновить свои manage.py. (Старый стиль manage.py будет продолжать работать как прежде до Django 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 }} должно быть заменено на имя пакета Python реального проекта.

Если настройки, URLconfs и приложения в проекте импортируются или ссылаются с использованием префикса имени проекта (например, 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 callable, что позволяет запускать runserver с той же конфигурацией WSGI, которая используется для развертывания. Новый параметр WSGI_APPLICATION позволяет настроить, какую WSGI callable использует runserver.

(Команда управления runfcgi также внутренне обертывает вызываемый модуль WSGI, настроенный через WSGI_APPLICATION).

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

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

Для более подробной информации смотрите документацию для select_for_update().

Model.objects.bulk_create в ORM

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

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

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

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

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

HTML5 doctype

Мы перевели шаблоны администратора и другие поставляемые шаблоны на использование HTML5 doctype. Хотя Django будет тщательно поддерживать совместимость со старыми браузерами, это изменение означает, что вы можете использовать любые необходимые вам функции HTML5 на страницах администратора без необходимости терять валидность HTML или переопределять поставляемые шаблоны для изменения doctype.

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

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

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

Список изменений администратора теперь поддерживает сортировку по нескольким столбцам. Она уважает все элементы атрибута ordering, а сортировка по нескольким столбцам путем нажатия на заголовки призвана имитировать поведение настольных графических интерфейсов. Мы также добавили метод get_ordering() для задания упорядочивания динамически (т.е. в зависимости от запроса).

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

Мы добавили метод save_related() к ModelAdmin, чтобы облегчить настройку того, как связанные объекты сохраняются в админке.

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

Административные линии уважают права пользователей

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

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

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

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

Мастер создания новой формы

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

Django 1.4 поставляется с бэкендом хранения данных на основе сессий и бэкендом хранения данных на основе куки. Последний использует инструменты для cryptographic signing, также представленные в Django 1.4, для хранения состояния мастера в cookies пользователя.

reverse_lazy

Добавлена лениво оцениваемая версия reverse(), позволяющая использовать обратные URL до загрузки URLconf проекта.

Перевод шаблонов URL

Django теперь может искать префикс языка в шаблоне URL при использовании новой вспомогательной функции i18n_patterns(). Также теперь можно определять переводимые шаблоны URL с помощью django.utils.translation.ugettext_lazy(). Смотрите Интернационализация: в шаблонах 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 contrib появился новый тег шаблона static для ссылки на файлы, сохраненные с помощью бэкенда хранилища STATICFILES_STORAGE. Он использует метод url бэкенда хранилища и поэтому поддерживает расширенные возможности, такие как serving files from a cloud service.

CachedStaticFilesStorage бэкэнд хранилища

Приложение staticfiles contrib теперь имеет django.contrib.staticfiles.storage.CachedStaticFilesStorage backend, который кэширует файлы, которые он сохраняет (при выполнении команды collectstatic management), добавляя 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() для проверки, содержит ли ответ клиента заданный фрагмент HTML. Подробнее см. в assertions documentation.

Две новые строки формата даты

Добавлены два новых формата date для использования в фильтрах шаблонов, тегах шаблонов и Локализация формата:

  • e – название временной зоны данного объекта datetime
  • o – номер года по стандарту ISO 8601

Пожалуйста, убедитесь, что вы обновили custom format files, если они содержат e или o в строке формата. Например, формат испанской локализации ранее экранировал только символ формата 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 также включает несколько более мелких улучшений, на которые стоит обратить внимание:

  • Более удобная трассировка стека на странице Technical 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 для генерации запросов SELECT, содержащих DISTINCT ON.

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

    Для более подробной информации смотрите документацию для distinct().

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

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

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

  • Фреймворк sitemaps теперь может обрабатывать ссылки HTTPS, используя новый атрибут класса Sitemap.protocol.

  • Новый подкласс django.test.SimpleTestCase от unittest.TestCase, который легче, чем django.test.TestCase и компания. Он может быть полезен в тестах, которым не нужно обращаться к базе данных. См. Иерархия классов модульного тестирования Django.

Изменения в 1.4, несовместимые с предыдущими версиями

Требуется настройка SECRET_KEY

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

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

django.contrib.admin

Включенное административное приложение django.contrib.admin долгое время поставлялось с набором статических файлов по умолчанию, таких как JavaScript, изображения и таблицы стилей. В Django 1.3 было добавлено новое приложение contrib 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 настроены и ваш веб-сервер правильно обслуживает эти файлы. Сервер разработки продолжает обслуживать файлы администратора, как и раньше. Прочитайте static files howto для более подробной информации.

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

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

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

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

В Django не было четкой политики относительно того, какие браузеры поддерживаются приложением администратора. Наша новая политика формализует существующую практику: YUI’s A-grade браузеры должны обеспечивать полнофункциональную работу администратора, за исключением Internet Explorer 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-») ко всем именам классов CSS, автоматически генерируемым из имен полей форм в главных админ-формах, стекированных инлайн-формах и табличных инлайн-ячейках. Вам нужно будет учесть этот префикс в ваших пользовательских таблицах стилей или файлах JavaScript, если вы ранее использовали обычные имена полей в качестве селекторов для пользовательских стилей или преобразований JavaScript.

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

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

Поэтому, если вы перейдете на Django 1.4 непосредственно с версии 1.2 или более ранней, вы можете потерять/недействить некоторые части данных, которые были криптографически подписаны старым методом. Чтобы избежать этого, используйте сначала Django 1.3 в течение некоторого времени, чтобы срок действия подписанных данных истек естественным образом. Затронутые части подробно описаны ниже, с указанием 1) последствий игнорирования этого совета и 2) количества времени, которое вам нужно запустить Django 1.3, чтобы данные истекли или стали неактуальными.

  • contrib.sessions проверка целостности данных
    • Последствия: Пользователь выйдет из системы, а данные сессии будут потеряны.
    • Период времени: Определяется SESSION_COOKIE_AGE.
  • contrib.auth хэш сброса пароля
    • Последствия: Ссылки на сброс пароля, созданные до обновления, не будут работать.
    • Период времени: Определяется PASSWORD_RESET_TIMEOUT_DAYS.

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

  • contrib.comments хэш безопасности формы
    • Последствия: Пользователь увидит ошибку проверки «Security hash failed».
    • Период времени: Количество времени, в течение которого, по вашим ожиданиям, пользователи будут заполнять формы для комментариев.
  • FormWizard хэш безопасности
    • Последствия: Пользователь увидит ошибку об истечении срока действия формы и будет возвращен на первую страницу мастера, потеряв введенные данные.
    • Период времени: Количество времени, в течение которого, по вашим ожиданиям, пользователи будут заполнять затронутые формы.
  • Проверка CSRF
    • Примечание: На самом деле это откат к Django 1.1, а не к Django 1.2, и он применим только в том случае, если вы переходите с версии 1.1.
    • Последствия: Пользователь увидит ошибку 403 при использовании любой CSRF-защищенной POST-формы.
    • Период времени: Количество времени, которое, по вашим ожиданиям, потребуется пользователю на заполнение таких форм.
  • contrib.auth пароль пользователя последовательность hash-upgrade
    • Последствия: Пароль каждого пользователя будет обновлен до более надежного хэша пароля при записи в базу данных в версии 1.4. Это означает, что если вы обновитесь до версии 1.4, а затем потребуется понижение до версии 1.3, версия 1.3 не сможет прочитать обновленные пароли.
    • Устранение: Установите PASSWORD_HASHERS для использования оригинального хэширования паролей при первоначальном обновлении до версии 1.4. После того, как вы убедитесь, что ваше приложение хорошо работает с Django 1.4 и вам не придется откатываться на 1.3, включите новые хэши паролей.

django.contrib.flatpages

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

Кроме того, перенаправления, возвращаемые плоскими страницами, теперь являются постоянными (с кодом статуса 301), чтобы соответствовать поведению CommonMiddleware.

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

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

  • Включает часовой пояс для известных объектов времени. Вызывает исключение для объектов с информацией о времени.
  • Он включает миллисекунды для объектов времени и даты. Потеря точности все же есть, поскольку Python хранит микросекунды (6 цифр), а JSON поддерживает только миллисекунды (3 цифры). Однако это лучше, чем полностью отбрасывать микросекунды.

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

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

supports_timezone изменено на False для SQLite

Функция базы данных supports_timezone раньше была True для SQLite. Действительно, если вы сохраняли объект datetime, SQLite сохранял строку, включающую смещение UTC. Однако это смещение игнорировалось при загрузке значения обратно из базы данных, что могло привести к повреждению данных.

В контексте поддержки временных зон этот флаг был изменен на False, и теперь в SQLite объекты времени сохраняются без информации о временных зонах. Когда USE_TZ равно False, при попытке сохранить объект datetime с информацией, Django вызывает исключение.

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

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

Локальность потока соединения с базой данных

<<< Объекты DatabaseWrapper (т.е. объекты соединения, на которые ссылаются django.db.connection и django.db.connections["some_alias"]) раньше были потоково-локальными. Теперь они стали глобальными объектами, чтобы их можно было использовать совместно в нескольких потоках. Хотя отдельные объекты соединений теперь глобальны, словарь 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 исторически поддерживали исключение комментариев специальной группы пользователей, но мы никогда не документировали эту возможность должным образом и не обеспечивали исключение в других частях приложения, таких как теги шаблонов. Чтобы исправить эту проблему, мы удалили код из класса feed.

Если вы полагаетесь на эту функцию и хотите восстановить старое поведение, используйте пользовательский менеджер модели комментариев, чтобы исключить группу пользователей, например, так:

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) и добавьте его в модель вашего пользовательского приложения комментариев:

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.3 можно было исключить некоторые URL из 404 error reporting, добавив префиксы к IGNORABLE_404_STARTS и суффиксы к IGNORABLE_404_ENDS.

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

Кроме того, предыдущие настройки имели довольно произвольные значения по умолчанию:

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

Ранее CSRF protection в Django обеспечивал защиту только от POST-запросов. Поскольку использование методов PUT и DELETE в AJAX-приложениях становится все более распространенным, теперь мы защищаем все методы, не определенные как безопасные в 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

Это был псевдоним django.template.loader с 2005 года, и мы удалили его без предупреждения из-за длительности депривации. Если ваш код все еще ссылается на него, пожалуйста, используйте django.template.loader вместо него.

django.db.models.fields.URLField.verify_exists

Эта функциональность была удалена из-за трудноразрешимых проблем с производительностью и безопасностью. Любое существующее использование verify_exists должно быть удалено.

django.core.files.storage.Storage.open

Метод open базового класса Storage принимал непонятный параметр mixin, который позволял динамически изменять базовые классы возвращаемого объекта файла. Этот параметр был удален. В редких случаях, когда вы полагались на параметр 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, полученный из ненадежного источника. Эта возможность не нужна для десериализатора YAML в Django, основное назначение которого - загрузка фикстур, состоящих из простых объектов. Несмотря на то, что фикстуры являются доверенными данными, десериализатор YAML теперь использует yaml.safe_load для дополнительной безопасности.

Куки сеанса теперь по умолчанию имеют флаг httponly

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

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

Когда URL содержит последовательность %xx, где xx - две шестнадцатеричные цифры, urlize теперь считает, что URL уже экранирован, и не применяет экранирование URL снова. Это неверно для URL, чья форма без кавычек содержит последовательность %xx, но такие URL очень маловероятны в природе, поскольку они также запутают браузеры.

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.

Подключения к базе данных после запуска тестового пакета

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

Если ваш код полагался на создание соединений с производственной базой данных после выполнения тестов, то вы можете восстановить прежнее поведение, подклассифицировав DjangoTestRunner и переопределив его метод teardown_databases().

Вывод 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

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

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

FormMixin get_initial возвращает словарь для конкретного экземпляра

В 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 в качестве минимальной версии PostgreSQL, которую он официально поддерживает.

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

Когда мы добавили logging support в Django в 1.3, поддержка писем об ошибках администратора была перенесена в django.utils.log.AdminEmailHandler, прикрепленный к логгеру 'django.request'. Чтобы сохранить устоявшееся поведение писем об ошибках, логгер 'django.request' вызывался только тогда, когда DEBUG был False.

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

'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 это станет предупреждением об устаревании, а в Django 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

Databrowse не был активно развит в течение некоторого времени, и это не имеет никаких признаков изменения. Было предложение GSOC project интегрировать функциональность databrowse в админку, но прогресс не был достигнут. Хотя 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_manager также устарела; вместо нее можно использовать execute_from_command_line. Ни одна из этих функций не документирована как часть общедоступного API, но путь устаревания необходим из-за использования в существующих файлах manage.py.

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

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

@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 *. К сожалению, это не может быть сделано надежно.

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

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

Этот атрибут был переименован в HttpRequest.raw_post_data, но на самом деле он представлял тело HTTP-запроса. Он был переименован в HttpRequest.body, а HttpRequest.raw_post_data был устаревшим.

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

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

Версии Python-Markdown ранее 2.1

Версии Python-Markdown ранее версии 2.1 не поддерживают возможность отключения атрибутов. В целях безопасности более ранние версии этой библиотеки не будут поддерживаться приложением markup contrib в версии 1.5 в соответствии с ускоренным графиком депривации.

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