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

2 сентября 2014

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

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

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

Для Django 1.7 требуется Python 2.7, 3.2, 3.3 или 3.4. Мы настоятельно рекомендуем и официально поддерживаем только последний выпуск каждой серии.

Серия Django 1.6 является последней, поддерживающей Python 2.6. Django 1.7 - первый релиз, поддерживающий Python 3.4.

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

Что нового в Django 1.7

Миграции схем

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

Миграции рассматриваются в their own documentation, но несколько ключевых особенностей таковы:

  • syncdb было устаревшим и заменено на migrate. Не волнуйтесь - вызовы syncdb будут работать как и раньше.

  • Новая команда makemigrations предоставляет простой способ автоопределения изменений в ваших моделях и создания миграций для них.

    django.db.models.signals.pre_syncdb и django.db.models.signals.post_syncdb были устаревшими, их заменили pre_migrate и post_migrate соответственно. Эти новые сигналы имеют немного другие аргументы. Подробности смотрите в документации.

  • Метод allow_syncdb на маршрутизаторах баз данных теперь называется allow_migrate, но выполняет ту же функцию. Маршрутизаторы с методами allow_syncdb будут по-прежнему работать, но это имя метода устарело, и вам следует изменить его как можно скорее (ничего большего, чем переименование, не требуется).

  • <<< Фиксы initial_data больше не загружаются для приложений с миграциями; если вы хотите загрузить начальные данные для приложения, мы предлагаем вам создать миграцию для вашего приложения и определить операцию RunPython или RunSQL в разделе operations миграции.

  • Тестовое поведение отката отличается для приложений с миграциями; в частности, Django больше не будет эмулировать откат на нетранзакционных базах данных или внутри TransactionTestCase unless specifically requested.

  • Не рекомендуется, чтобы приложения без миграций зависели от (имели отношение ForeignKey или ManyToManyField к) приложений с миграциями.

Рефактор загрузки приложений

Исторически приложения Django были тесно связаны с моделями. Модуль, известный как «app cache», работал как с установленными приложениями, так и с моделями. Модуль models использовался в качестве идентификатора приложений во многих API.

По мере развития концепции Django applications этот код показал некоторые недостатки. Он был рефакторингован в «реестр приложений», где модули моделей больше не играют центральной роли и где можно прикреплять данные конфигурации к приложениям.

К числу усовершенствований относятся:

  • Приложения могут запускать код при старте, до того, как Django сделает что-либо еще, с помощью метода ready() в их конфигурации.
  • Ярлыки приложений правильно назначаются моделям, даже если они определены вне models.py. Вам больше не нужно явно задавать app_label.
  • Можно полностью опустить models.py, если приложение не имеет никаких моделей.
  • Приложения могут быть перемаркированы с помощью атрибута label в конфигурациях приложений, чтобы обойти конфликты меток.
  • Название приложений можно настроить в администраторе с помощью verbose_name конфигураций приложений.
  • Администратор автоматически вызывает autodiscover() при запуске Django. Следовательно, вы можете удалить эту строку из вашего URLconf.
  • Django импортирует все конфигурации и модели приложения сразу после его запуска, посредством детерминированного и простого процесса. Это должно облегчить диагностику проблем импорта, таких как зацикливание импорта.

Новый метод для подклассов полей

Чтобы облегчить миграцию схем и добавить составные ключи в будущих выпусках Django, API Field теперь имеет новый необходимый метод: deconstruct().

Этот метод не принимает аргументов и возвращает кортеж из четырех элементов:

  • name: Имя атрибута поля в его родительской модели, или None, если оно не является частью модели.
  • path: Пунктирный, Python-путь к классу этого поля, включая имя класса.
  • args: Позиционные аргументы, в виде списка
  • kwargs: Аргументы ключевых слов, в виде диктанта

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

Это изменение не должно повлиять на вас, если вы не пишете пользовательские подклассы Field; в этом случае вам, возможно, придется заново реализовать метод deconstruct(), если ваш подкласс каким-либо образом изменит сигнатуру метода __init__. Если ваше поле просто наследуется от встроенного поля Django и не переопределяет __init__, то никаких изменений не требуется.

Если вам нужно переопределить deconstruct(), хорошим местом для начала являются встроенные поля Django (django/db/models/fields/__init__.py), поскольку несколько полей, включая DecimalField и DateField, переопределяют его и показывают, как вызвать метод на суперклассе и просто добавить или удалить дополнительные аргументы.

Это также означает, что все аргументы полей должны быть сериализуемыми; чтобы узнать, что мы считаем сериализуемым, и как сделать свои собственные классы сериализуемыми, прочитайте migration serialization documentation.

Вызов пользовательских методов QuerySet из Manager

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

Хотя это не документировано, было принято обходить эту проблему путем создания пользовательского QuerySet, чтобы пользовательские методы могли быть связаны в цепочку; но это решение имело ряд недостатков:

  • Пользовательский QuerySet и его пользовательские методы были потеряны после первого вызова values() или values_list().
  • Написание пользовательского Manager все еще было необходимо для возврата пользовательского класса QuerySet, и все методы, которые были нужны на Manager, должны были быть проксированы на QuerySet. Весь процесс шел вразрез с принципом DRY.

Метод класса QuerySet.as_manager() теперь может напрямую create Manager with QuerySet methods:

class FoodQuerySet(models.QuerySet):
    def pizzas(self):
        return self.filter(kind='pizza')

    def vegetarian(self):
        return self.filter(vegetarian=True)

class Food(models.Model):
    kind = models.CharField(max_length=50)
    vegetarian = models.BooleanField(default=False)
    objects = FoodQuerySet.as_manager()

Food.objects.pizzas().vegetarian()

Использование пользовательского менеджера при обходе обратных отношений

Теперь можно specify a custom manager при обходе обратного отношения:

class Blog(models.Model):
    pass

class Entry(models.Model):
    blog = models.ForeignKey(Blog)

    objects = models.Manager()  # Default Manager
    entries = EntryManager()    # Custom Manager

b = Blog.objects.get(id=1)
b.entry_set(manager='entries').all()

Новая система проверки системы

Мы добавили новую функцию System check framework для обнаружения распространенных проблем (например, недействительных моделей) и предоставления подсказок для их решения. Фреймворк является расширяемым, поэтому вы можете добавлять собственные проверки для своих приложений и библиотек.

Для выполнения проверки системы используется команда check management. Эта команда заменяет более старую команду управления validate.

Ярлыки администратора поддерживают часовые пояса

Ярлыки «сегодня» и «сейчас» рядом с виджетами ввода даты и времени в админке теперь работают в режиме current time zone. Ранее они использовали часовой пояс браузера, что могло привести к сохранению неверного значения, если оно не совпадало с текущим часовым поясом на сервере.

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

Использование курсоров базы данных в качестве менеджеров контекста

До Python 2.7 курсоры баз данных можно было использовать в качестве менеджера контекста. Курсор конкретного бэкенда определял поведение контекстного менеджера. В Python 2.7 поведение магических методов поиска было изменено, и курсоры перестали использоваться в качестве менеджеров контекста.

Django 1.7 позволяет использовать курсор в качестве менеджера контекста. То есть, можно использовать следующее:

with connection.cursor() as c:
    c.execute(...)

вместо:

c = connection.cursor()
try:
    c.execute(...)
finally:
    c.close()

Пользовательский поиск

Теперь стало возможным писать пользовательские поиски и преобразования для ORM. Пользовательский поиск работает так же, как и встроенный поиск Django (например, lte, icontains), а преобразования - это новая концепция.

Класс django.db.models.Lookup предоставляет возможность добавления операторов поиска для полей модели. В качестве примера можно добавить оператор day_lte для DateFields.

Класс django.db.models.Transform позволяет преобразовывать значения базы данных до окончательного поиска. Например, можно написать преобразование year, которое извлекает год из значения поля. Преобразования позволяют выстраивать цепочки. После того как преобразование year было добавлено к DateField, можно фильтровать преобразованное значение, например qs.filter(author__birthdate__year__lte=1981).

Для получения дополнительной информации о пользовательских поисках и преобразованиях обратитесь к документации custom lookups.

Улучшения в обработке ошибок Form

Form.add_error()

Ранее существовало два основных шаблона для обработки ошибок в формах:

  • Вызов ValidationError из некоторых функций (например, Field.clean(), Form.clean_<fieldname>() или Form.clean() для ошибок, не связанных с полем).
  • Неправильное использование Form._errors при нацеливании на конкретное поле в Form.clean() или добавление ошибок извне «чистого» метода (например, непосредственно из представления).

Использование первого шаблона было простым, так как форма может определить по контексту (т.е. какой метод вызвал исключение), где находятся ошибки, и автоматически обработать их. Это остается каноническим способом добавления ошибок, когда это возможно. Однако второй способ был сложным и чреватым ошибками, поскольку бремя обработки крайних случаев ложилось на пользователя.

Новый метод add_error() позволяет добавлять ошибки в определенные поля формы из любого места, не заботясь о таких деталях, как создание экземпляров django.forms.utils.ErrorList или работа с Form.cleaned_data. Этот новый API заменяет манипуляции с Form._errors, которые теперь становятся частным API.

Пример использования Очистка и проверка полей, которые зависят друг от друга см. в Form.add_error().

Метаданные об ошибках

Конструктор ValidationError принимает метаданные, такие как ошибка code или params, которые затем доступны для интерполяции в сообщение об ошибке (подробнее см. Поднятие ValidationError); однако до Django 1.7 эти метаданные отбрасывались, как только ошибки добавлялись в Form.errors.

Form.errors и django.forms.utils.ErrorList теперь хранят экземпляры ValidationError, поэтому эти метаданные могут быть получены в любое время с помощью нового метода Form.errors.as_data.

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

Новый метод Form.errors.as_json() - это удобный метод, который возвращает сообщения об ошибках вместе с кодами ошибок, сериализованными в виде JSON. as_json() использует as_data() и дает представление о том, как можно расширить новую систему.

Контейнеры ошибок и обратная совместимость

Для поддержки вышеуказанных возможностей потребовались значительные изменения в различных контейнерах ошибок, в частности Form.errors, django.forms.utils.ErrorList и внутренних хранилищах ValidationError. Эти контейнеры, которые раньше хранили строки ошибок, теперь хранят экземпляры ValidationError, и публичные API были адаптированы, чтобы сделать это как можно более прозрачным, но если вы использовали частные API, некоторые изменения будут обратно несовместимы; смотрите ValidationError конструктор и внутреннее хранилище для более подробной информации.

Незначительные особенности

django.contrib.admin

  • Теперь вы можете реализовать атрибуты site_header, site_title и index_title на пользовательском AdminSite, чтобы легко изменить заголовок и текст заголовка страницы администратора сайта. Больше не нужно переопределять шаблоны!
  • Кнопки в django.contrib.admin теперь используют свойство CSS border-radius для закругленных углов, а не фоновые изображения GIF.
  • Некоторые шаблоны администраторов теперь имеют классы app-<app_name> и model-<model_name> в теге <body>, что позволяет настраивать CSS для каждого приложения или модели.
  • Ячейки списка изменений администратора теперь имеют класс field-<field_name> в HTML для возможности настройки стиля.
  • Поисковые поля администратора теперь можно настраивать по каждому запросу благодаря новому методу django.contrib.admin.ModelAdmin.get_search_fields().
  • Метод ModelAdmin.get_fields() может быть переопределен для настройки значения ModelAdmin.fields.
  • В дополнение к существующему синтаксису admin.site.register, вы можете использовать новый декоратор register() для регистрации ModelAdmin.
  • Вы можете указать ModelAdmin.list_display_links = None, чтобы отключить ссылки на сетке страницы списка изменений.
  • Теперь вы можете указать ModelAdmin.view_on_site, чтобы контролировать, отображать или нет ссылку «Посмотреть на сайте».
  • Вы можете задать нисходящий порядок для значения ModelAdmin.list_display, предваряя значение admin_order_field дефисом.
  • Метод ModelAdmin.get_changeform_initial_data() может быть переопределен, чтобы определить пользовательское поведение для установки начальных данных формы изменения.

django.contrib.auth

  • Любые **kwargs, переданные в email_user(), передаются в базовый вызов send_mail().
  • Декоратор permission_required() может принимать как список разрешений, так и одно разрешение.
  • Вы можете переопределить новый метод AuthenticationForm.confirm_login_allowed() для более простой настройки политики входа.
  • django.contrib.auth.views.password_reset() принимает необязательный параметр html_email_template_name, используемый для отправки многокомпонентного HTML письма для сброса пароля.
  • Был добавлен метод AbstractBaseUser.get_session_auth_hash(), и если ваш AUTH_USER_MODEL наследует от AbstractBaseUser, изменение пароля пользователя теперь аннулирует старые сессии, если django.contrib.auth.middleware.SessionAuthenticationMiddleware включен. См. Аннулирование сессии при смене пароля для более подробной информации.

django.contrib.formtools

  • Вызовы WizardView.done() теперь включают form_dict, чтобы облегчить доступ к формам по имени шага.

django.contrib.gis

  • Версия библиотеки OpenLayers, по умолчанию включаемая в виджеты, была обновлена с 2.11 до 2.13.
  • Подготовленные геометрии теперь также поддерживают предикаты crosses, disjoint, overlaps, touches и within, если установлена GEOS 3.3 или более поздняя версия.

django.contrib.messages

  • Бэкенды для django.contrib.messages, использующие cookies, теперь будут следовать настройкам SESSION_COOKIE_SECURE и SESSION_COOKIE_HTTPONLY.
  • messages context processor теперь добавляет словарь уровней по умолчанию под именем DEFAULT_MESSAGE_LEVELS.
  • Объекты Message теперь имеют атрибут level_tag, который содержит строковое представление уровня сообщения.

django.contrib.redirects

django.contrib.sessions

  • Бэкенд сессии "django.contrib.sessions.backends.cached_db" теперь уважает SESSION_CACHE_ALIAS. В предыдущих версиях он всегда использовал кэш default.

django.contrib.sitemaps

  • Теперь sitemap framework использует lastmod для установки заголовка Last-Modified в ответе. Это позволяет ConditionalGetMiddleware обрабатывать условные GET запросы для карт сайта, которые устанавливают lastmod.

django.contrib.sites

django.contrib.staticfiles

  • static files storage classes может быть подклассифицирован для переопределения разрешений, которые получают собранные статические файлы и каталоги, путем установки параметров file_permissions_mode и directory_permissions_mode. Пример использования см. в collectstatic.

  • Бэкэнд CachedStaticFilesStorage получает родственный класс ManifestStaticFilesStorage, который вообще не использует систему кэширования, а вместо этого использует JSON файл staticfiles.json для хранения связки между оригинальным именем файла (например, css/styles.css) и хэшированным именем файла (например, css/styles.55e7cbb9ba48.css). Файл staticfiles.json создается при выполнении команды управления collectstatic и должен стать менее затратной альтернативой для удаленных хранилищ, таких как Amazon S3.

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

  • findstatic теперь принимает флаг многословности уровня 2, что означает, что он будет показывать относительные пути каталогов, в которых производился поиск. Пример вывода см. в findstatic.

django.contrib.syndication

  • Элемент Atom1Feed синдикационного фида updated теперь использует updateddate вместо pubdate, что позволяет включить в фид элемент published (который полагается на pubdate).

Кэш

  • Доступ к кэшам, настроенным в CACHES, теперь доступен через django.core.cache.caches. Этот диктоподобный объект предоставляет разные экземпляры для каждого потока. Он заменяет django.core.cache.get_cache(), который теперь устарел.
  • Если вы создаете кэш-бэкенды напрямую, имейте в виду, что они больше не потокобезопасны, так как django.core.cache.caches теперь дает разные экземпляры для каждого потока.
  • Определение аргумента TIMEOUT параметра CACHES как None установит ключи кэша по умолчанию как «неистекающие». Ранее можно было передавать timeout=None только в метод set() бэкенда кэша.

Подделка межсайтовых запросов

  • Настройка CSRF_COOKIE_AGE облегчает использование CSRF-куки на основе сеанса.

Электронная почта

  • send_mail() теперь принимает параметр html_message для отправки многокомпонентного text/plain и text/html письма.
  • SMTP EmailBackend теперь принимает параметр timeout.

Хранение файлов

  • Ранее блокировка файлов в Windows зависела от пакета PyWin32; если он не был установлен, блокировка файлов не работала. Эта зависимость была удалена, и теперь блокировка файлов реализована нативно как в Windows, так и в Unix.

Загрузка файлов

  • Новый атрибут UploadedFile.content_type_extra содержит дополнительные параметры, передаваемые в заголовок content-type при загрузке файла.
  • Новый параметр FILE_UPLOAD_DIRECTORY_PERMISSIONS управляет разрешениями файловой системы для каталогов, созданных во время загрузки файлов, подобно тому, как FILE_UPLOAD_PERMISSIONS управляет разрешениями для самих файлов.
  • Атрибут FileField.upload_to теперь является необязательным. Если он опущен или указан None или пустая строка, подкаталог не будет использоваться для хранения загруженных файлов.
  • Загруженные файлы теперь явно закрываются перед передачей ответа клиенту. Частично загруженные файлы также закрываются, если в обработчике загрузки им присвоено имя file.
  • Storage.get_available_name() теперь добавляет знак подчеркивания плюс случайную 7-символьную буквенно-цифровую строку (например, "_x3a1gho"), а не итерацию через знак подчеркивания, за которым следует число (например, "_1", "_2" и т.д.) для предотвращения атаки типа «отказ в обслуживании». Это изменение также было внесено в релизы безопасности 1.6.6, 1.5.9 и 1.4.14.

Формы

  • Теги <label> и <input>, выводимые RadioSelect и CheckboxSelectMultiple при переходе по радиокнопкам или чекбоксам, теперь включают атрибуты for и id соответственно. Каждая радиокнопка или чекбокс включает атрибут id_for_label для вывода идентификатора элемента.
  • Теги <textarea>, отображаемые Textarea, теперь включают атрибут maxlength, если поле модели TextField имеет max_length.
  • Field.choices теперь позволяет настроить метку «пустой выбор», включив в нее кортеж с пустой строкой или None в качестве ключа и пользовательской меткой в качестве значения. Опция пустого выбора по умолчанию "----------" в этом случае будет опущена.
  • MultiValueField позволяет использовать необязательные подполя, установив аргумент require_all_fields в значение False. Атрибут required для каждого отдельного поля будет соблюдаться, и новая ошибка валидации incomplete будет возникать, если какие-либо обязательные поля пусты.
  • Метод clean() на форме больше не должен возвращать self.cleaned_data. Если он возвращает измененный словарь, то он все равно будет использоваться.
  • После временной регрессии в Django 1.6 теперь снова можно заставить метод TypedChoiceField coerce возвращать произвольное значение.
  • SelectDateWidget.months можно использовать для настройки формулировки месяцев, отображаемых в виджете выбора.
  • Параметры min_num и validate_min были добавлены к formset_factory(), чтобы обеспечить валидацию минимального количества отправленных форм.
  • Метаклассы, используемые Form и ModelForm, были переработаны для поддержки большего количества сценариев наследования. Предыдущее ограничение, которое не позволяло наследовать одновременно от Form и ModelForm, было устранено, если ModelForm появляется первым в MRO.
  • Теперь можно удалить поле из Form при подклассификации, установив имя в None.
  • Теперь можно настраивать сообщения об ошибках для ограничений ModelForm unique, unique_for_date и unique_together. Для поддержки unique_together или любого другого NON_FIELD_ERROR, ModelForm теперь ищет NON_FIELD_ERROR ключ в error_messages словаре внутреннего ModelForm класса Meta. Более подробную информацию смотрите в considerations regarding model’s error_messages.

Интернационализация

  • Атрибут django.middleware.locale.LocaleMiddleware.response_redirect_class позволяет настраивать перенаправления, выдаваемые промежуточным ПО.
  • Константа LocaleMiddleware теперь хранит выбранный пользователем язык с ключом сессии _language. Доступ к нему можно получить только с помощью константы LANGUAGE_SESSION_KEY. Ранее он хранился с ключом django_language, а константы LANGUAGE_SESSION_KEY не существовало, но ключи, зарезервированные для Django, должны начинаться с символа подчеркивания. Для обратной совместимости django_language по-прежнему считывается из 1.7. Сессии будут переводиться на новый ключ по мере их записи.
  • Тег blocktrans теперь поддерживает опцию trimmed. Эта опция удаляет символы новой строки из начала и конца содержимого тега {% blocktrans %}, заменяет любые пробельные символы в начале и конце строки и объединяет все строки в одну, используя символ пробела для их разделения. Это очень полезно для отступа содержимого тега {% blocktrans %} без того, чтобы символы отступа попадали в соответствующую запись в PO-файле, что облегчает процесс перевода.
  • Когда вы запускаете makemessages из корневого каталога вашего проекта, все извлеченные строки теперь будут автоматически распространяться в соответствующий файл сообщений приложения или проекта. Подробности смотрите в Локализация: как создавать языковые файлы.
  • Команда makemessages теперь всегда добавляет флаг командной строки --previous к команде msgmerge, сохраняя ранее переведенные строки в файлах po для нечетких строк.
  • Были введены следующие параметры для настройки опций языкового cookie: LANGUAGE_COOKIE_AGE, LANGUAGE_COOKIE_DOMAIN и LANGUAGE_COOKIE_PATH.
  • Добавлено Локализация формата для эсперанто.

Команды управления

  • Новая опция --no-color для django-admin отключает окрашивание вывода команд управления.

  • Новые опции dumpdata --natural-foreign и dumpdata --natural-primary, а также новые аргументы use_natural_foreign_keys и use_natural_primary_keys для serializers.serialize() позволяют использовать естественные первичные ключи при сериализации.

  • Больше нет необходимости указывать имя таблицы кэша или опцию --database для команды createcachetable. Django берет эту информацию из вашего файла настроек. Если вы настроили несколько кэшей или несколько баз данных, создаются все таблицы кэша.

  • Команда runserver получила несколько улучшений:

    • В системах Linux, если установлен pyinotify, сервер разработки будет перезагружаться немедленно при изменении файла. Ранее он опрашивал файловую систему на предмет изменений каждую секунду. Это вызывало небольшую задержку перед перезагрузкой и сокращало время работы от батареи на ноутбуках.
    • Кроме того, сервер разработки автоматически перезагружается при обновлении файла перевода, т.е. после выполнения команды compilemessages.
    • Все HTTP-запросы записываются в консоль, включая запросы на статические файлы или favicon.ico, которые раньше отфильтровывались.
  • Команды управления теперь могут выдавать синтаксически окрашенный вывод под Windows, если установлен и активен сторонний инструмент ANSICON.

  • Команда collectstatic с опцией symlink теперь поддерживается в Windows NT 6 (Windows Vista и новее).

  • Исходные данные SQL теперь работают лучше, если установлена библиотека sqlparse Python.

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

Модели

  • Добавлен метод QuerySet.update_or_create().
  • Новая опция default_permissions модели Meta позволяет настроить (или отключить) создание разрешений по умолчанию на добавление, изменение и удаление.
  • Явные OneToOneField для Мультитабличное наследование теперь обнаруживаются в абстрактных классах.
  • Теперь можно избежать создания обратной связи для OneToOneField, установив его related_name в '+' или завершив его '+'.
  • F expressions поддерживают оператор мощности (**).
  • Методы remove() и clear() связанных менеджеров, созданных ForeignKey и GenericForeignKey, теперь принимают аргумент ключевого слова bulk для управления тем, выполнять ли операции массово (т.е. используя QuerySet.update()). По умолчанию используется True.
  • Теперь можно использовать None в качестве значения запроса для поиска iexact.
  • Теперь можно передавать вызываемый объект в качестве значения для атрибута limit_choices_to при определении ForeignKey или ManyToManyField.
  • Вызов only() и defer() по результату QuerySet.values() теперь вызывает ошибку (раньше это приводило либо к ошибке базы данных, либо к неверным данным).
  • Вы можете использовать один список для index_together (а не список списков) при указании одного набора полей.
  • Пользовательские промежуточные модели, имеющие более одного внешнего ключа к любой из моделей, участвующих в отношениях «многие ко многим», теперь разрешены, если вы явно укажете, какие внешние ключи должны использоваться, задав новый аргумент ManyToManyField.through_fields.
  • Присвоение экземпляра модели полю, не являющемуся полем взаимосвязи, теперь приводит к ошибке. Ранее это срабатывало, если поле принимало целые числа в качестве входных данных, поскольку оно принимало первичный ключ.
  • Целочисленные поля теперь проверяются на соответствие минимальным и максимальным значениям, определенным бэкендом базы данных, на основе их internal_type. Ранее проверка полей модели не предотвращала сохранение значений вне диапазона типа данных соответствующего столбца, что приводило к ошибке целостности.
  • Теперь можно явно order_by() поле отношения _id, используя имя его атрибута.

Сигналы

  • Аргумент enter был добавлен к сигналу setting_changed.
  • К сигналам модели теперь можно подключать с помощью str формы 'app_label.ModelName' - так же, как и связанные поля - для ленивой ссылки на их отправителей.

Шаблоны

  • Метод Context.push() теперь возвращает менеджер контекста, который автоматически вызывает pop() при выходе из оператора with. Кроме того, push() теперь принимает параметры, которые передаются в конструктор dict, используемый для создания нового контекстного уровня.
  • Новый метод Context.flatten() возвращает стек Context в виде одного плоского словаря.
  • Объекты Context теперь можно сравнивать на равенство (внутренне, для этого используется Context.flatten(), поэтому внутренняя структура стека каждого Context не имеет значения, пока их уплощенная версия идентична).
  • Тег шаблона widthratio теперь принимает параметр "as" для записи результата в переменную.
  • Тег шаблона include теперь также будет принимать в качестве аргумента все, что имеет метод render() (например, Template). Строковые аргументы, как всегда, будут искаться с помощью get_template().
  • Теперь можно include шаблоны рекурсивно.
  • Объекты шаблонов теперь имеют атрибут origin, установленный, когда TEMPLATE_DEBUG является True. Это позволяет проверять и регистрировать происхождение шаблонов вне инфраструктуры django.template.
  • Исключения TypeError больше не замалчиваются при возникновении во время рендеринга шаблона.
  • Следующие функции теперь принимают параметр dirs, который представляет собой список или кортеж для переопределения TEMPLATE_DIRS:
  • Фильтр time теперь принимает связанные с временными зонами format specifiers 'e', 'O' , 'T' и 'Z' и способен переварить time-zone-aware datetime экземпляры, выполняя ожидаемый рендеринг.
  • Тег cache теперь будет пытаться использовать кэш под названием «template_fragments», если он существует, и возвращаться к использованию кэша по умолчанию в противном случае. Также теперь он принимает необязательный аргумент using с ключевым словом для управления тем, какой кэш он использует.
  • Новый фильтр truncatechars_html обрезает строку до длины, не превышающей указанного количества символов, с учетом HTML.

Запросы и ответы

  • Новый атрибут HttpRequest.scheme определяет схему запроса (обычно http или https).
  • Ярлык redirect() теперь поддерживает относительные URL.
  • Новый подкласс JsonResponse HttpResponse помогает легко создавать JSON-кодированные ответы.

Тесты

  • DiscoverRunner имеет два новых атрибута, test_suite и test_runner, которые облегчают переопределение способа сбора и запуска тестов.
  • Аргумент fetch_redirect_response был добавлен к assertRedirects(). Поскольку тестовый клиент не может получать внешние URL, это позволяет вам использовать assertRedirects с перенаправлениями, которые не являются частью вашего приложения Django.
  • Корректная обработка схемы при выполнении сравнений в assertRedirects().
  • Аргумент secure был добавлен ко всем методам запроса Client. Если True, запрос будет выполняться через HTTPS.
  • assertNumQueries() теперь выводит список выполненных запросов, если утверждение не прошло.
  • Экземпляр WSGIRequest, созданный обработчиком теста, теперь присоединен к атрибуту django.test.Response.wsgi_request.
  • Настройки базы данных для тестирования были собраны в словарь с именем TEST.

Утилиты

  • Улучшена точность strip_tags() (но по-прежнему не гарантирует HTML-безопасный результат, как указано в документации).

Валидаторы

  • RegexValidator теперь принимает необязательный flags и булевский inverse_match аргументы. Атрибут inverse_match определяет, должен ли подниматься флаг ValidationError, когда шаблон регулярного выражения соответствует (True) или не соответствует (False, по умолчанию) предоставленному value. Атрибут flags устанавливает флаги, используемые при компиляции строки регулярного выражения.
  • URLValidator теперь принимает необязательный аргумент schemes, который позволяет настраивать принимаемые схемы URI (вместо значений по умолчанию http(s) и ftp(s)).
  • validate_email() теперь принимает адреса с литералами IPv6, например example@[2001:db8::1], как указано в RFC 5321.

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

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

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

allow_syncdb / allow_migrate

Хотя Django по-прежнему будет рассматривать методы allow_syncdb, даже если их следует переименовать в allow_migrate, существует тонкая разница в том, какие модели передаются этим методам.

Для приложений с миграциями, allow_migrate теперь будет передаваться historical models, которые представляют собой специальные версионные модели без пользовательских атрибутов, методов или менеджеров. Убедитесь, что ваши методы allow_migrate ссылаются только на поля или другие элементы в model._meta.

начальные_данные

Приложения с миграциями не будут загружать фикстуры initial_data после завершения миграции. Приложения без миграций будут продолжать загружать эти фикстуры во время фазы migrate, что эмулирует старое поведение syncdb, но любые новые приложения не будут иметь такой поддержки.

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

Кроме того, как и остальной старый код Django syncdb, initial_data был запущен по пути депривации и будет удален в Django 1.9.

deconstruct() и сериализуемость

Django теперь требует, чтобы все классы Field и все аргументы их конструкторов были сериализуемыми. Если вы каким-либо образом измените сигнатуру конструктора в вашем пользовательском Field, вам нужно будет реализовать метод deconstruct(); мы расширили документацию по пользовательским полям с помощью instructions on implementing this method.

Требование, чтобы все аргументы поля были serializable, означает, что любые экземпляры пользовательских классов, передаваемые в конструкторы Field - например, такие вещи, как пользовательские подклассы Storage - должны иметь deconstruct method defined on them as well, хотя Django предоставляет удобный декоратор классов, который подойдет для большинства приложений.

Изменения в загрузке приложений

Последовательность запуска

Django 1.7 загружает конфигурации и модели приложения сразу после запуска. Хотя такое поведение более простое и считается более надежным, нельзя исключать регрессии. Смотрите Устранение неполадок для решения некоторых проблем, с которыми вы можете столкнуться.

Автономные сценарии

Если вы используете Django в обычном сценарии Python - а не в команде управления - и полагаетесь на переменную окружения DJANGO_SETTINGS_MODULE, то теперь вы должны явно инициализировать Django в начале вашего сценария с помощью:

>>> import django
>>> django.setup()

В противном случае вы столкнетесь с исключением AppRegistryNotReady.

Скрипты WSGI

До версии Django 1.3 рекомендуемым способом создания WSGI-приложения был:

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

В Django 1.4 была улучшена поддержка WSGI, а API изменился на:

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

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

Согласованность реестра приложений

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

Если у вас есть два приложения с одинаковыми метками, вам следует создать AppConfig для одного из них и переопределить там label. Затем вам следует скорректировать свой код везде, где он ссылается на это приложение или его модели со старым ярлыком.

Теперь невозможно импортировать одну и ту же модель дважды через разные пути. Начиная с Django 1.6, это может произойти, только если вы вручную помещаете каталог и подкаталог на PYTHONPATH. Обратитесь к разделу о новой схеме проекта в 1.4 release notes для получения инструкций по миграции.

Вы должны убедиться в этом:

  • Все модели определены в приложениях, которые перечислены в INSTALLED_APPS или имеют явный app_label.
  • Модели не импортируются как побочный эффект загрузки приложения. В частности, не следует импортировать модели ни в корневой модуль приложения, ни в модуль, определяющий его класс конфигурации.

Django будет применять эти требования начиная с версии 1.9, после периода устаревания.

Подклассификация AppCommand

Подклассы AppCommand теперь должны реализовывать метод handle_app_config() вместо handle_app(). Этот метод получает экземпляр AppConfig вместо модуля модели.

Приложения для интроспекции

Поскольку INSTALLED_APPS теперь поддерживает классы конфигурации приложений в дополнение к модулям приложений, вам следует пересмотреть код, который обращается к этой настройке напрямую, и вместо этого использовать реестр приложений (django.apps.apps).

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

  • get_model повышает LookupError вместо возврата None, когда модель не найдена.
  • Аргумент only_installed из get_model и get_models больше не существует, как и аргумент seed_cache из get_model.

Команды управления и порядок выполнения INSTALLED_APPS

Когда несколько приложений предоставляют команды управления с одинаковым именем, Django загружает команду из приложения, которое стоит первым в INSTALLED_APPS. Предыдущие версии загружали команду из приложения, которое пришло последним.

Это приводит открытие команд управления в соответствие с другими частями Django, которые полагаются на порядок INSTALLED_APPS, такими как статические файлы, шаблоны и переводы.

ValidationError конструктор и внутреннее хранилище

Поведение конструктора ValidationError изменилось, когда он получает в качестве аргумента контейнер ошибок (например, list или ErrorList):

  • Он преобразует все найденные строки в экземпляры ValidationError, прежде чем добавить их в свое внутреннее хранилище.
  • Он не хранит данный контейнер, а копирует его содержимое в собственное внутреннее хранилище; ранее сам контейнер добавлялся к экземпляру ValidationError и использовался в качестве внутреннего хранилища.

Это означает, что если вы обращаетесь к внутренним хранилищам ValidationError, таким как error_list; error_dict; или к возвращаемому значению update_error_dict(), вы можете найти экземпляры ValidationError там, где раньше вы нашли бы строки.

Также если вы напрямую присвоили возвращаемое значение update_error_dict() к Form._errors, вы можете случайно добавить list экземпляры там, где ожидалось ErrorList экземпляры. Это проблема, потому что в отличие от простого list, ErrorList знает, как обрабатывать экземпляры ValidationError.

Большинство случаев, которые оправдывали использование этих частных API, теперь покрываются недавно представленным методом Form.add_error():

# Old pattern:
try:
    # ...
except ValidationError as e:
    self._errors = e.update_error_dict(self._errors)

# New pattern:
try:
    # ...
except ValidationError as e:
    self.add_error(None, e)

Если вам нужна совместимость с Django <= 1.6 и 1.7, вы не можете использовать Form.add_error(), поскольку он не был доступен до Django 1.7, но вы можете использовать следующее обходное решение для преобразования любого list в ErrorList:

try:
    # ...
except ValidationError as e:
    self._errors = e.update_error_dict(self._errors)

# Additional code to ensure ``ErrorDict`` is exclusively
# composed of ``ErrorList`` instances.
for field, error_list in self._errors.items():
    if not isinstance(error_list, self.error_class):
        self._errors[field] = self.error_class(error_list)

Поведение LocMemCache относительно ошибок pickle

В предыдущих версиях Django существовало несоответствие в том, как ошибки pickle обрабатываются различными бэкендами кэша. django.core.cache.backends.locmem.LocMemCache раньше молча завершался при возникновении такой ошибки, что несовместимо с другими бэкендами и приводит к ошибкам, специфичным для кэша. Это было исправлено в Django 1.7, смотрите #21200 для более подробной информации.

Ключи кэша теперь генерируются из абсолютного URL запроса

Предыдущие версии Django генерировали ключи кэша, используя путь запроса и строку запроса, но не схему или хост. Если приложение Django обслуживало несколько поддоменов или доменов, ключи кэша могли столкнуться. В Django 1.7 ключи кэша зависят от абсолютного URL запроса, включая схему, хост, путь и строку запроса. Например, часть URL в кэш-ключе теперь генерируется из https://www.example.com/path/to/?key=val, а не /path/to/?key=val. Ключи кэша, генерируемые Django 1.7, будут отличаться от ключей, генерируемых более ранними версиями Django. После обновления до Django 1.7 первый запрос к любому ранее кэшированному URL будет пропуском кэша.

Передача None в Manager.db_manager()

В предыдущих версиях Django можно было использовать db_manager(using=None) для экземпляра менеджера модели, чтобы получить экземпляр менеджера, использующий стандартное поведение маршрутизации, переопределяя любую вручную заданную маршрутизацию базы данных. В Django 1.7 значение None, переданное в db_manager, создаст маршрутизатор, который сохранит любую назначенную вручную маршрутизацию базы данных - менеджер не будет сброшен. Это было необходимо для устранения несоответствия в способе каскадирования информации о маршрутизации по соединениям. Более подробную информацию смотрите в #13724.

pytz может потребоваться

Если ваш проект работает с датами до 1970 или после 2037 года и Django при встрече с ними выдает ошибку ValueError, вам необходимо установить pytz. Вы можете столкнуться с этой проблемой, если используете форматы дат, связанные с часовыми поясами в Django, или django.contrib.syndication.

Стратегия перенаправления входа в систему администратора

Исторически сложилось так, что административный сайт Django передавал запрос от неавторизованного или не прошедшего аутентификацию пользователя непосредственно на страницу входа в систему, без HTTP-перенаправления. В Django 1.7 это поведение изменилось в соответствии с более традиционным рабочим процессом, где любой неавторизованный запрос к странице администратора будет перенаправлен (по коду статуса HTTP 302) на страницу входа в систему, с параметром next>, установленным на ссылающийся путь. Пользователь будет перенаправлен туда после успешного входа.

Обратите также внимание, что форма входа в систему администратора была обновлена и теперь не содержит поля this_is_the_login_form (теперь не используется), а код ValidationError был установлен на более обычный ключ invalid_login.

select_for_update() требует транзакции

Исторически запросы, использующие select_for_update(), могли выполняться в режиме автокоммита, вне транзакции. До Django 1.6 режим автоматических транзакций Django позволял использовать это для блокировки записей до следующей операции записи. В Django 1.6 появился автокоммит на уровне базы данных; с тех пор выполнение в таком контексте аннулирует эффект от select_for_update(). Поэтому теперь это считается ошибкой и вызывает исключение.

Это изменение было сделано потому, что такие ошибки могут быть вызваны включением приложения, которое ожидает глобальных транзакций (например, ATOMIC_REQUESTS установлено в True), или старого поведения Django autocommit, в проект, который работает без них; и далее, такие ошибки могут проявляться как ошибки повреждения данных. Это также было сделано в Django 1.6.3.

Это изменение может привести к сбоям в тестировании, если вы используете select_for_update() в тестовом классе, который является подклассом TransactionTestCase, а не TestCase.

Contrib промежуточное ПО удалено из стандартного MIDDLEWARE_CLASSES

В app-loading refactor устарело использование моделей из приложений, которые не являются частью настройки INSTALLED_APPS. Это выявило несовместимость между настройками по умолчанию INSTALLED_APPS и MIDDLEWARE_CLASSES в глобальных настройках по умолчанию (django.conf.global_settings). Чтобы привести эти настройки в соответствие и предотвратить предупреждения об устаревании при выполнении таких действий, как тестирование многократно используемых приложений с минимальными настройками, SessionMiddleware, AuthenticationMiddleware и MessageMiddleware были удалены из значений по умолчанию. Эти классы по-прежнему будут включены в настройки по умолчанию, генерируемые startproject. На большинство проектов это изменение не повлияет, но если вы ранее не объявляли MIDDLEWARE_CLASSES в настройках проекта и полагались на глобальные настройки по умолчанию, вам следует убедиться, что новые настройки по умолчанию соответствуют потребностям вашего проекта. Также следует проверить любой код, который обращается к django.conf.global_settings.MIDDLEWARE_CLASSES напрямую.

Разное

  • Методу django.core.files.uploadhandler.FileUploadHandler.new_file() теперь передается дополнительный параметр content_type_extra. Если у вас есть пользовательский FileUploadHandler, который реализует new_file(), убедитесь, что он принимает этот новый параметр.

  • ModelFormSets больше не удаляет экземпляры при вызове save(commit=False). Смотрите can_delete для инструкций по ручному удалению объектов из удаленных форм.

  • Загрузка пустых фикстур выдает RuntimeWarning, а не поднимает CommandError.

  • django.contrib.staticfiles.views.serve() теперь будет вызывать исключение Http404 вместо ImproperlyConfigured, когда DEBUG будет False. Это изменение устраняет необходимость условно добавлять представление в корневой URLconf, что, в свою очередь, делает безопасным обратный переход по имени. Оно также устраняет возможность для посетителей генерировать ложные ошибки HTTP 500, запрашивая статические файлы, которые не существуют или еще не были собраны.

  • Метод django.db.models.Model.__eq__() теперь определен таким образом, что экземпляры прокси-модели и ее базовой модели считаются равными при совпадении первичных ключей. Ранее при совпадении первичных ключей равными считались только экземпляры точно такого же класса.

  • Метод django.db.models.Model.__eq__() изменился таким образом, что два экземпляра Model без значений первичного ключа не будут считаться равными (если только они не являются одним и тем же экземпляром).

  • Метод django.db.models.Model.__hash__() теперь будет вызывать TypeError при вызове экземпляра без значения первичного ключа. Это сделано для того, чтобы избежать изменяемых __hash__ значений в контейнерах.

  • Колонки AutoField в базах данных SQLite теперь будут создаваться с использованием опции AUTOINCREMENT, которая гарантирует монотонное приращение. Это приведет к изменению поведения нумерации первичных ключей в SQLite, которое станет соответствовать большинству других баз данных SQL. Это относится только к вновь созданным таблицам. Если у вас есть база данных, созданная в более старой версии Django, вам нужно будет перенести ее, чтобы воспользоваться этой возможностью. Например, вы можете сделать следующее:

    1. Используйте dumpdata для сохранения данных.
    2. Переименуйте существующий файл базы данных (сохраните его в качестве резервной копии).
    3. Выполните migrate, чтобы создать обновленную схему.
    4. Используйте loaddata для импорта приспособлений, которые вы экспортировали в (1).
  • django.contrib.auth.models.AbstractUser больше не определяет метод get_absolute_url(). Старое определение возвращало "/users/%s/" % urlquote(self.username), что было произвольным, поскольку приложения могут определять или не определять такой url в urlpatterns. Определите метод get_absolute_url() на вашем собственном пользовательском объекте или используйте ABSOLUTE_URL_OVERRIDES, если вам нужен URL для вашего пользователя.

  • Функциональность класса django.test.LiveServerTestCase по обслуживанию статических активов была упрощена: Теперь он способен обслуживать только содержимое, уже присутствующее в STATIC_ROOT при выполнении тестов. Возможность прозрачно обслуживать все статические активы (аналогично тому, как это происходит с DEBUG = True во время разработки) была перенесена в новый класс, который живет в приложении staticfiles (которое, собственно, и отвечает за эту функцию): django.contrib.staticfiles.testing.StaticLiveServerTestCase. Другими словами, сам LiveServerTestCase стал менее мощным, но в то же время в нем меньше магии.

    Основанием для этого является устранение зависимости неконтрибутивного кода от приложений contrib.

  • Старый синтаксис URI кэша (например, "locmem://") больше не поддерживается. Он все еще работал, хотя не был документирован или официально поддерживался. Если вы все еще используете его, пожалуйста, обновите его до текущего синтаксиса CACHES.

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

  • Аргумент required из SelectDateWidget был удален. Теперь этот виджет уважает атрибут is_required поля формы, как и другие виджеты.

  • Widget.is_hidden теперь является свойством только для чтения, получая свое значение путем интроспекции наличия input_type == 'hidden'.

  • select_related() теперь цепляется так же, как и другие подобные вызовы, например prefetch_related. То есть, select_related('foo', 'bar') эквивалентен select_related('foo').select_related('bar'). Ранее последний был эквивалентен select_related('bar').

  • GeoDjango отказался от поддержки GEOS < 3.1.

  • Метод init_connection_state бэкендов баз данных теперь выполняется в режиме автокоммита (если вы не установили AUTOCOMMIT в False). Если вы поддерживаете пользовательский бэкенд базы данных, вам следует проверить этот метод.

  • Атрибут django.db.backends.BaseDatabaseFeatures.allows_primary_key_0 был переименован в allows_auto_pk_0, чтобы лучше его описать. Это True для всех бэкендов баз данных, включенных в Django, кроме MySQL, который разрешает первичные ключи со значением 0. Он только запрещает автоинкрементные первичные ключи со значением 0.

  • Тень полей модели, определенных в родительской модели, была запрещена, поскольку это создает двусмысленность в ожидаемом поведении модели. Кроме того, столкновение полей в иерархии наследования модели приводит к ошибке проверки системы. Например, если вы используете мультинаследование, вам необходимо определить пользовательские поля первичного ключа в родительских моделях, иначе поля по умолчанию id будут конфликтовать. Подробнее см. в разделе Множественное наследование.

  • django.utils.translation.parse_accept_lang_header() теперь возвращает локали в нижнем регистре, а не в том регистре, в котором они были предоставлены. Поскольку локали должны обрабатываться без учета регистра, это позволяет нам ускорить определение локали.

  • django.utils.translation.get_language_from_path() и django.utils.translation.trans_real.get_supported_language_variant() больше не имеют аргумента supported.

  • Представление shortcut в django.contrib.contenttypes.views теперь поддерживает относительные по протоколу URL (например, //example.com).

  • GenericRelation теперь поддерживает необязательный аргумент related_query_name. Установка related_query_name добавляет отношение от связанного объекта обратно к типу содержимого для фильтрации, упорядочивания и других операций запроса.

  • При выполнении тестов на PostgreSQL, USER будет необходим доступ на чтение к встроенной базе данных postgres. Это заменяет предыдущее поведение подключения к реальной нетестовой базе данных.

  • Как часть System check framework, fields, models, and model managers все реализуют метод check(), который регистрируется в фреймворке проверки. Если у вас есть существующий метод с именем check() на одном из этих объектов, вам нужно будет переименовать его.

  • Как было отмечено выше в разделе «Кэш» раздела «Незначительные возможности», определение аргумента TIMEOUT параметра CACHES как None установит ключи кэша как «неистекающие». Ранее, при использовании бэкенда memcache, параметр TIMEOUT, равный 0, устанавливал неистекающие ключи, но это не соответствовало поведению параметра set("key", "value", timeout=0) «установил-и-истек» (т.е. без кэширования). Если вам нужны неистекающие ключи, пожалуйста, обновите настройки, чтобы использовать None вместо 0, так как последний теперь также обозначает set-and-expire в настройках.

  • Команды управления sql* теперь уважают метод allow_migrate() из DATABASE_ROUTERS. Если у вас есть модели, синхронизированные с базами данных не по умолчанию, используйте флаг --database, чтобы получить SQL для этих моделей (ранее они всегда включались в вывод).

  • Декодирование строки запроса из URL теперь возвращается к кодировке ISO-8859-1, когда входные данные не являются действительными UTF-8.

  • С добавлением django.contrib.auth.middleware.SessionAuthenticationMiddleware в шаблон проекта по умолчанию (только до версии 1.7.2), база данных должна быть создана перед обращением к странице, использующей runserver.

  • Добавление аргумента schemes к URLValidator будет выглядеть как несовместимое с прошлым изменение, если вы ранее использовали пользовательское регулярное выражение для проверки схем. Любая схема, не указанная в schemes, не пройдет проверку, даже если регулярное выражение соответствует заданному URL.

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

django.core.cache.get_cache

django.core.cache.get_cache был вытеснен django.core.cache.caches.

django.utils.dictconfig/django.utils.importlib

django.utils.dictconfig и django.utils.importlib были копиями соответственно logging.config и importlib, предусмотренными для версий Python до 2.7. Они были устаревшими.

django.utils.module_loading.import_by_path

Текущая функция django.utils.module_loading.import_by_path перехватывает исключения AttributeError, ImportError и ValueError, и повторно вызывает ImproperlyConfigured. Такая маскировка исключений излишне затрудняет диагностику проблем с циркулярным импортом, поскольку создается впечатление, что проблема исходит изнутри Django. Она была упразднена в пользу import_string().

django.utils.tzinfo

django.utils.tzinfo предоставлял два подкласса tzinfo, LocalTimezone и FixedOffset. Они были упразднены в пользу более корректных альтернатив, предоставляемых django.utils.timezone, django.utils.timezone.get_default_timezone() и django.utils.timezone.get_fixed_timezone().

django.utils.unittest

django.utils.unittest обеспечивал единообразный доступ к библиотеке unittest2 на всех версиях Python. Поскольку unittest2 стал модулем стандартной библиотеки unittest в Python 2.7, а Django 1.7 отказался от поддержки старых версий Python, этот модуль больше не нужен. Он был устаревшим. Вместо него используйте unittest.

django.utils.datastructures.SortedDict

Поскольку OrderedDict был добавлен в стандартную библиотеку в Python 2.7, SortedDict больше не нужен и был устаревшим.

Два дополнительных, устаревших метода, предоставляемых SortedDict (insert() и value_for_index()) были удалены. Если вы использовали эти методы для изменения структур, таких как поля формы, то теперь вы должны рассматривать эти OrderedDicts как неизменяемые объекты и переопределять их для изменения их содержимого.

Например, вы можете переопределить MyFormClass.base_fields (хотя этот атрибут не считается публичным API), чтобы изменить порядок полей для всех экземпляров MyFormClass; или аналогично, вы можете переопределить self.fields изнутри MyFormClass.__init__(), чтобы изменить поля для конкретного экземпляра формы. Например (из самого Django):

PasswordChangeForm.base_fields = OrderedDict(
    (k, PasswordChangeForm.base_fields[k])
    for k in ['old_password', 'new_password1', 'new_password2']
)

Пользовательское местоположение SQL для пакета моделей

Ранее, если модели были организованы в пакет (myapp/models/), а не просто myapp/models.py, Django искал исходные данные SQL в myapp/models/sql/. Эта ошибка была исправлена, так что Django будет искать в myapp/sql/, как это и задокументировано. После того, как эта проблема была исправлена, были добавлены миграции, которые обесценивают начальные данные SQL. Таким образом, хотя это изменение все еще существует, устаревание не имеет значения, так как вся функция будет удалена в Django 1.9.

Реорганизация django.contrib.sites

django.contrib.sites предоставляет урезанную функциональность, когда она не находится в INSTALLED_APPS. Рефактор загрузки приложений добавляет некоторые ограничения в этой ситуации. Как следствие, два объекта были перемещены, а старые местоположения устарели:

  • RequestSite теперь живет в django.contrib.sites.requests.
  • get_current_site() теперь живет в django.contrib.sites.shortcuts.

declared_fieldsets атрибут включен ModelAdmin

ModelAdmin.declared_fieldsets был устаревшим. Несмотря на то, что это частный API, он пройдет через обычный путь депривации. Этот атрибут в основном использовался методами, которые обходили ModelAdmin.get_fieldsets(), но это считалось ошибкой и было устранено.

Реорганизация django.contrib.contenttypes

Поскольку django.contrib.contenttypes.generic определял объекты, связанные как с администратором, так и с моделью, импорт этого модуля мог вызвать неожиданные побочные эффекты. Как следствие, его содержимое было разделено на подмодули contenttypes, а модуль django.contrib.contenttypes.generic устарел:

syncdb

Команда syncdb была устаревшей в пользу новой команды migrate. migrate принимает те же аргументы, что и syncdb, плюс еще несколько, поэтому безопасно просто изменить имя, которое вы вызываете, и ничего больше.

Модули util переименованы в utils

Следующие экземпляры util.py в кодовой базе Django были переименованы в utils.py в попытке унифицировать все ссылки на util и utils:

  • django.contrib.admin.util
  • django.contrib.gis.db.backends.util
  • django.db.backends.util
  • django.forms.util

get_formsets метод на ModelAdmin

ModelAdmin.get_formsets был устаревшим в пользу нового get_formsets_with_inlines(), чтобы лучше обрабатывать случай выборочного показа строк на ModelAdmin.

IPAddressField

Поля django.db.models.IPAddressField и django.forms.IPAddressField были упразднены в пользу django.db.models.GenericIPAddressField и django.forms.GenericIPAddressField.

BaseMemcachedCache._get_memcache_timeout метод

Метод BaseMemcachedCache._get_memcache_timeout() был переименован в get_backend_timeout(). Несмотря на то, что это частный API, он будет проходить через обычную депривацию.

Варианты сериализации естественных ключей

Опции --natural и -n для dumpdata были устаревшими. Вместо них используйте dumpdata --natural-foreign.

Аналогично, аргумент use_natural_keys для serializers.serialize() был устаревшим. Вместо него используйте use_natural_foreign_keys.

Объединение аргументов POST и GET в WSGIRequest.REQUEST

Уже было настоятельно рекомендовано использовать GET и POST вместо REQUEST, поскольку первые более явные. Свойство REQUEST является устаревшим и будет удалено в Django 1.9.

django.utils.datastructures.MergeDict класс

MergeDict существует в основном для поддержки объединения аргументов POST и GET в свойство REQUEST на WSGIRequest. Для слияния словарей используйте dict.update(). Класс MergeDict является устаревшим и будет удален в Django 1.9.

Языковые коды zh-cn, zh-tw и fy-nl

Используемые в настоящее время коды языков для упрощенного китайского zh-cn, традиционного китайского zh-tw и (западного) фризского fy-nl устарели и должны быть заменены кодами языков zh-hans, zh-hant и fy соответственно. Если вы используете эти языковые коды, вам следует переименовать каталоги локалей и обновить настройки, чтобы отразить эти изменения. Устаревшие языковые коды будут удалены в Django 1.9.

django.utils.functional.memoize функция

Функция memoize является устаревшей и должна быть заменена декоратором functools.lru_cache (доступен начиная с Python 3.2).

Django поставляет бэкпорт этого декоратора для старых версий Python, и он доступен по адресу django.utils.lru_cache.lru_cache. Устаревшая функция будет удалена в Django 1.9.

Geo Sitemaps

Google прекратил поддержку формата Geo Sitemaps. Следовательно, поддержка Geo Sitemaps в Django устарела и будет удалена в Django 1.8.

Передача вызываемых аргументов в методы queryset

Вызываемые аргументы для querysets были недокументированной функцией, которая была ненадежной. Она была устаревшей и будет удалена в Django 1.9.

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

ADMIN_FOR установка

Функция ADMIN_FOR, часть admindocs, была удалена. Вы можете удалить этот параметр из своей конфигурации по своему усмотрению.

SplitDateTimeWidget с DateTimeField

Поддержка SplitDateTimeWidget в DateTimeField устарела, вместо этого используйте SplitDateTimeWidget с SplitDateTimeField.

validate

Команда управления validate устарела в пользу команды check.

django.core.management.BaseCommand

requires_model_validation устарел в пользу нового флага requires_system_checks. Если последний флаг отсутствует, то используется значение первого флага. Определение как requires_system_checks, так и requires_model_validation приводит к ошибке.

Метод check() заменил старый метод validate().

ModelAdmin валидаторы

Атрибуты ModelAdmin.validator_class и default_validator_class устарели в пользу нового атрибута checks_class.

Метод ModelAdmin.validate() устарел в пользу ModelAdmin.check().

Модуль django.contrib.admin.validation является устаревшим.

django.db.backends.DatabaseValidation.validate_field

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

Загрузка тегов шаблонов ssi и url из библиотеки future

Django 1.3 ввел синтаксис {% load ssi from future %} и {% load url from future %} для совместимости с тегами шаблонов ssi и url. Сейчас этот синтаксис устарел и будет удален в Django 1.9. Вы можете просто удалить теги {% load ... from future %}.

django.utils.text.javascript_quote

javascript_quote() была недокументированной функцией, присутствующей в django.utils.text. Она использовалась внутри представления javascript_catalog(), реализация которого была изменена для использования вместо нее json.dumps(). Если вы полагаетесь на эту функцию для обеспечения безопасного вывода недоверенных строк, вам следует использовать django.utils.html.escapejs или фильтр шаблона escapejs. Если все, что вам нужно, это генерировать допустимые строки JavaScript, вы можете просто использовать json.dumps().

fix_ampersands метод utils и фильтр шаблонов

Метод django.utils.html.fix_ampersands и фильтр шаблона fix_ampersands устарели, поскольку экранирование амперсандов уже выполняется стандартными функциями экранирования HTML в Django. Комбинация этого метода с fix_ampersands приведет либо к двойному экранированию, либо, если вывод предполагается безопасным, к риску появления XSS-уязвимостей. Наряду с fix_ampersands устарела django.utils.html.clean_html - недокументированная функция, вызывающая fix_ampersands. Поскольку это ускоренная депривация, fix_ampersands и clean_html будут удалены в Django 1.8.

Реорганизация настроек тестирования базы данных

Все настройки базы данных с префиксом TEST_ были устаревшими в пользу записей в словаре TEST в настройках базы данных. Старые настройки будут поддерживаться до версии Django 1.9. Для обратной совместимости со старыми версиями Django, вы можете определить обе версии настроек, если они совпадают.

Поддержка FastCGI

Поддержка FastCGI через команду управления runfcgi будет удалена в Django 1.9. Пожалуйста, развертывайте ваш проект, используя WSGI.

Перемещение объектов в contrib.sites

После рефактора загрузки приложений два объекта в django.contrib.sites.models необходимо было переместить, поскольку они должны быть доступны без импорта django.contrib.sites.models, когда django.contrib.sites не установлен. Импортируйте RequestSite из django.contrib.sites.requests и get_current_site() из django.contrib.sites.shortcuts. Старые места импорта будут работать до версии Django 1.9.

django.forms.forms.get_declared_fields()

Django больше не использует этот функционал внутри компании. Несмотря на то, что это приватный API, он пройдет через обычный цикл депривации.

API для поиска частных запросов

Частные API django.db.models.sql.where.WhereNode.make_atom() и django.db.models.sql.where.Constraint устарели в пользу нового custom lookups API.

Функции, удаленные в 1.7

Эти функции достигли конца своего цикла устаревания и будут удалены в Django 1.7. Смотрите Функции, устаревшие в версии 1.5 для подробностей, включая то, как удалить использование этих функций.

  • django.utils.simplejson удаляется.
  • django.utils.itercompat.product удаляется.
  • INSTALLED_APPS и TEMPLATE_DIRS больше не исправляются из простой строки в кортеж.
  • HttpResponse, SimpleTemplateResponse, TemplateResponse, render_to_response(), index() и sitemap() больше не принимают аргумент mimetype
  • HttpResponse немедленно потребляет его содержимое, если это итератор.
  • Настройка AUTH_PROFILE_MODULE и метод get_profile() в модели User удалены.
  • Команда управления cleanup удалена.
  • Скрипт daily_cleanup.py удален.
  • select_related() больше не имеет аргумента в виде ключевого слова depth.
  • Функции get_warnings_state()/restore_warnings_state() из django.test.utils и save_warnings_state()/ restore_warnings_state() django.test.*TestCase удалены.
  • Метод check_for_test_cookie в AuthenticationForm удален.
  • Версия django.contrib.auth.views.password_reset_confirm(), поддерживающая идентификаторы пользователей в кодировке base36 (django.contrib.auth.views.password_reset_confirm_uidb36), удалена.
  • Смесь django.utils.encoding.StrAndUnicode удалена.
Вернуться на верх