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

Апрель 4, 2017

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

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

См. руководство Обновление Django до более новой версии, если вы обновляете существующий проект.

Django 1.11 обозначен как long-term support release. Она будет получать обновления безопасности в течение как минимум трех лет после выпуска. Поддержка предыдущей LTS, Django 1.8, закончится в апреле 2018 года.

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

Django 1.11 требует Python 2.7, 3.4, 3.5, 3.6 или 3.7 (по состоянию на 1.11.17). Мы настоятельно рекомендуем и официально поддерживаем только последний выпуск каждой серии.

Серия Django 1.11.x является последней, поддерживающей Python 2. Следующий основной выпуск, Django 2.0, будет поддерживать только Python 3.4+.

Амортизирующие предупреждения больше не являются громкими по умолчанию

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

Это изменение позволяет сторонним приложениям поддерживать как Django 1.11 LTS, так и Django 1.8 LTS без необходимости добавлять код, чтобы избежать предупреждений об устаревании.

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

Что нового в Django 1.11

Модельные индексы на основе классов

Новый модуль django.db.models.indexes содержит классы, облегчающие создание индексов базы данных. Индексы добавляются к моделям с помощью опции Meta.indexes.

Класс Index создает индекс b-дерева, как если бы вы использовали db_index на поле модели или index_together на модели Meta. Он может быть подклассифицирован для поддержки различных типов индексов, например GinIndex. Он также позволяет определить порядок (ASC/DESC) для столбцов индекса.

Рендеринг виджетов на основе шаблонов

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

Возможно, вам придется скорректировать любые пользовательские виджеты, которые вы написали для нескольких backwards incompatible changes.

Subquery выражения

Новые выражения базы данных Subquery и Exists позволяют создавать явные подзапросы. Подзапросы могут ссылаться на поля из внешнего набора запросов с помощью класса OuterRef.

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

django.contrib.admin

  • ModelAdmin.date_hierarchy теперь может ссылаться на поля в разных отношениях.
  • Новый хук ModelAdmin.get_exclude() позволяет указать исключаемые поля на основе запроса или экземпляра модели.
  • Шаблон popup_response.html теперь может быть переопределен для каждого приложения, для каждой модели или путем установки атрибута ModelAdmin.popup_response_template.

django.contrib.auth

  • Количество итераций по умолчанию для хешера паролей PBKDF2 увеличено на 20%.
  • Представления LoginView и LogoutView на основе классов заменяют устаревшие представления login() и logout() на основе функций.
  • Представления на основе классов PasswordChangeView, PasswordChangeDoneView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView и PasswordResetCompleteView заменяют устаревшие представления на основе функций password_change(), password_change_done(), password_reset(), password_reset_done(), password_reset_confirm() и password_reset_complete().
  • Новый атрибут post_reset_login для PasswordResetConfirmView позволяет автоматически регистрировать пользователя после успешного сброса пароля. Если у вас настроено несколько AUTHENTICATION_BACKENDS, используйте атрибут post_reset_login_backend, чтобы выбрать, какой из них использовать.
  • Чтобы избежать возможности утечки маркера сброса пароля через заголовок HTTP Referer (например, если страница сброса содержит ссылку на CSS или JavaScript, размещенные на другом домене), PasswordResetConfirmView (но не устаревшее представление на основе функции password_reset_confirm()) хранит маркер в сессии и перенаправляет на себя, чтобы представить пользователю форму изменения пароля без маркера в URL.
  • update_session_auth_hash() теперь поворачивает сессионный ключ, чтобы смена пароля аннулировала украденные сессионные cookies.
  • Новый атрибут success_url_allowed_hosts для LoginView и LogoutView позволяет указать набор хостов, безопасных для перенаправления после входа и выхода из системы.
  • Добавлены валидаторы паролей help_text к UserCreationForm.
  • Теперь HttpRequest передается в authenticate(), который в свою очередь передает его бэкенду аутентификации, если он принимает аргумент request.
  • Сигнал user_login_failed() теперь получает аргумент request.
  • PasswordResetForm поддерживает пользовательские модели пользователей, которые используют поле электронной почты с именем, отличным от 'email'. Установите CustomUser.EMAIL_FIELD на имя поля.
  • get_user_model() теперь можно вызывать во время импорта, даже в модулях, определяющих модели.

django.contrib.contenttypes

  • При обнаружении устаревших типов содержимого в команде remove_stale_contenttypes теперь есть список связанных объектов, таких как auth.Permissions, которые также будут удалены. Ранее перечислялись только типы содержимого (и эта подсказка была после команды migrate, а не в отдельной команде).

django.contrib.gis

  • Новые методы GEOSGeometry.from_gml() и OGRGeometry.from_gml() позволяют создавать геометрии из GML.
  • Добавлена поддержка поиска dwithin в SpatiaLite.
  • Функция Area, функция Distance и поиск расстояний теперь работают с геодезическими координатами на SpatiaLite.
  • Виджеты форм на основе OpenLayers теперь используют OpenLayers.js из https://cdnjs.cloudflare.com, который больше подходит для производственного использования, чем старый источник https://openlayers.org/. Они также обновлены для использования OpenLayers 3.
  • Миграции PostGIS теперь могут изменять размеры полей.
  • Добавлена возможность передавать параметры size, shape и offset при создании объектов GDALRaster.
  • Добавлена поддержка SpatiaLite для функции IsValid, функции MakeValid и поиска isvalid.
  • Добавлена поддержка Oracle для функций AsGML, BoundingCircle, IsValid и isvalid.

django.contrib.postgres

  • Новый аргумент distinct для StringAgg определяет, будут ли конкатенированные значения различаться.
  • Новые классы GinIndex и BrinIndex позволяют создавать GIN и BRIN индексы в базе данных.
  • JSONField принимает новый параметр encoder для указания пользовательского класса для кодирования типов данных, не поддерживаемых стандартным кодировщиком.
  • Новый миксин CIText и операция миграции CITextExtension позволяют использовать расширение PostgreSQL citext для поиска без учета регистра. Предусмотрено три поля: CICharField, CIEmailField и CITextField.
  • Новый JSONBAgg позволяет агрегировать значения в виде массива JSON.
  • HStoreField (поле модели) и HStoreField (поле формы) позволяют хранить нулевые значения.

Кэш

  • Бэкенды Memcached теперь передают содержимое OPTIONS в качестве аргументов ключевых слов в конструкторы клиента, что позволяет более детально контролировать поведение клиента. Примеры смотрите в документации по cache arguments.
  • Бэкенды Memcached теперь позволяют определять несколько серверов в виде строки, разделенной запятыми в LOCATION, для удобства работы со сторонними сервисами, которые используют такие строки в переменных окружения.

CSRF

  • Добавлена настройка CSRF_USE_SESSIONS, позволяющая хранить CSRF-токен в сессии пользователя, а не в cookie.

Бэкенды баз данных

  • Добавлен аргумент skip_locked к QuerySet.select_for_update() на PostgreSQL 9.5+ и Oracle для выполнения запросов с FOR UPDATE SKIP LOCKED.
  • Добавлена настройка TEST['TEMPLATE'], позволяющая пользователям PostgreSQL указывать шаблон для создания тестовой базы данных.
  • QuerySet.iterator() теперь использует server-side cursors на PostgreSQL. Эта функция переносит часть нагрузки рабочей памяти (используемой для хранения результатов запроса) на базу данных и может увеличить использование памяти базы данных.
  • Добавлена поддержка MySQL для опции 'isolation_level' в OPTIONS, позволяющая указывать transaction isolation level. Чтобы избежать возможной потери данных, рекомендуется перейти с уровня MySQL по умолчанию, повторяющегося чтения, на чтение с фиксацией.
  • Добавлена поддержка cx_Oracle 5.3.

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

  • Добавлена настройка EMAIL_USE_LOCALTIME, позволяющая отправлять заголовки даты SMTP в местном часовом поясе, а не в UTC.
  • EmailMessage.attach() и attach_file() теперь возвращаются к MIME-типу application/octet-stream, когда двоичное содержимое, которое не может быть декодировано как UTF-8, указано для вложения text/*.

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

  • Чтобы сделать его оборачиваемым io.TextIOWrapper, File теперь имеет методы readable(), writable() и seekable().

Формы

  • Новый атрибут CharField.empty_value позволяет указать значение Python для представления «пусто».
  • Новый метод Form.get_initial_for_field() возвращает начальные данные для поля формы.

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

  • Форматирование чисел и настройка NUMBER_GROUPING поддерживают неравномерную группировку цифр.

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

  • Новая опция loaddata --exclude позволяет исключить модели и приложения при загрузке данных из приспособлений.
  • Новая опция diffsettings --default позволяет указать модуль настроек, отличный от настроек Django по умолчанию, с которым будет проводиться сравнение.
  • app_labels аргументы теперь ограничивают вывод showmigrations --plan.

Миграции

  • Добавлена поддержка сериализации объектов uuid.UUID.

Модели

  • Добавлена поддержка вызываемых значений в аргументе defaults в QuerySet.update_or_create() и get_or_create().
  • ImageField теперь имеет валидатор по умолчанию validate_image_file_extension. (Этот валидатор переместился в поле формы в Django 1.11.2).
  • Добавлена поддержка усечения времени в функции Trunc.
  • Добавлена функция ExtractWeek для извлечения недели из DateField и DateTimeField и выставления ее через поиск week.
  • Добавлена функция TruncTime для усечения DateTimeField до его временной составляющей и раскрытия его через поиск time.
  • Добавлена поддержка выражений в QuerySet.values() и values_list().
  • Добавлена поддержка выражений запросов для поиска, принимающих несколько аргументов, таких как range.
  • Теперь вы можете использовать опцию unique=True с FileField.
  • Добавлены параметры nulls_first и nulls_last к Expression.asc() и desc() для управления упорядочиванием нулевых значений.
  • Новые методы F выражение bitleftshift() и bitrightshift() позволяют bitwise shift operations.
  • Добавлены QuerySet.union(), intersection() и difference().

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

  • Добавлено QueryDict.fromkeys().
  • CommonMiddleware теперь устанавливает заголовок ответа Content-Length для непотоковых ответов.
  • Добавлена настройка SECURE_HSTS_PRELOAD, позволяющая добавлять директиву preload к заголовку Strict-Transport-Security.
  • ConditionalGetMiddleware теперь добавляет заголовок ETag к ответам.

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

  • Новый атрибут django.core.serializers.base.Serializer.stream_class позволяет подклассам настраивать поток по умолчанию.
  • Кодер, используемый функцией JSON serializer, теперь можно настроить, передав аргумент с ключевым словом cls в функцию serializers.serialize().
  • DjangoJSONEncoder теперь сериализует объекты timedelta (используемые DurationField).

Шаблоны

  • mark_safe() теперь можно использовать в качестве декоратора.
  • Бэкенд шаблона Jinja2 теперь поддерживает контекстные процессоры путем установки опции 'context_processors' в OPTIONS.
  • Тег regroup теперь возвращает namedtuples вместо словарей, так что вы можете распаковать объект группы непосредственно в цикле, например, {% for grouper, list in regrouped %}.
  • Добавлен тег шаблона resetcycle, позволяющий сбросить последовательность тега шаблона cycle.
  • Теперь вы можете указать конкретные каталоги для определенного filesystem.Loader.

Тесты

  • Добавлено DiscoverRunner.get_test_runner_kwargs() для возможности настройки аргументов ключевых слов, передаваемых в программу запуска тестов.
  • Добавлена опция test --debug-mode для облегчения поиска неисправностей при тестировании путем установки параметра DEBUG в значение True.
  • Новые функции django.test.utils.setup_databases() (перенесены из django.test.runner) и teardown_databases() облегчают создание пользовательских прогонов тестов.
  • Добавлена поддержка unittest.TestCase.subTest() при использовании опции test --parallel.
  • DiscoverRunner теперь запускает системные проверки в начале выполнения теста. Переопределите метод DiscoverRunner.run_checks(), если вы хотите отключить его.

Валидаторы

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

django.contrib.gis

  • Для упрощения кодовой базы и потому, что его легче установить, чем когда contrib.gis был впервые выпущен, GDAL теперь является обязательной зависимостью для GeoDjango. В старых версиях она требовалась только для SQLite.
  • contrib.gis.maps удален, поскольку он взаимодействует с устаревшей версией API Google Maps и, похоже, не поддерживается. Если вы используете его, let us know.
  • Оператор равенства GEOSGeometry теперь также сравнивает SRID.
  • Виджеты форм на основе OpenLayers теперь используют OpenLayers 3, а шаблоны gis/openlayers.html и gis/openlayers-osm.html были обновлены. Проверьте свой проект, если вы используете подклассы этих виджетов или расширяете шаблоны. Кроме того, новые виджеты работают немного иначе, чем старые. Вместо использования панели инструментов в виджете, вы нажимаете кнопку мыши, чтобы нарисовать, нажимаете и перетаскиваете, чтобы переместить карту, и нажимаете и перетаскиваете точку/вершину/угол, чтобы переместить ее.
  • Поддержка SpatiaLite < 4.0 прекращена.
  • Поддержка GDAL 1.7 и 1.8 прекращена.
  • Виджеты в contrib.gis.forms.widgets и админке OpenLayersWidget используют form rendering API, а не loader.render_to_string(). Если вы используете пользовательский шаблон виджета, вам нужно убедиться, что ваш рендерер формы может его найти. Например, вы можете использовать рендерер TemplatesSetting.

django.contrib.staticfiles

  • collectstatic теперь может не сработать во время постобработки при использовании хэшированного статического хранилища файлов, если существует цикл ссылок (например, 'foo.css' ссылается на 'bar.css', который сам ссылается на 'foo.css') или если цепочка файлов, ссылающихся на другие файлы, слишком глубока, чтобы разрешить ее за несколько проходов. В последнем случае увеличьте количество проходов, используя ManifestStaticFilesStorage.max_post_process_passes.
  • При использовании ManifestStaticFilesStorage статические файлы, не найденные в манифесте во время выполнения, теперь вызывают ошибку ValueError вместо возврата неизменного пути. Вы можете вернуться к старому поведению, установив ManifestStaticFilesStorage.manifest_strict в False.

API бэкенда базы данных

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

  • Метод DatabaseOperations.time_trunc_sql() добавлен для поддержки усечения TimeField. Он принимает аргументы lookup_type и field_name и возвращает соответствующий SQL для усечения заданного поля времени field_name до объекта времени только с заданной спецификой. Аргумент lookup_type может быть либо 'hour', 'minute', либо 'second'.
  • Метод DatabaseOperations.datetime_cast_time_sql() добавлен для поддержки поиска time. Он принимает аргументы field_name и tzname и возвращает SQL, необходимый для приведения значения времени к значению времени.
  • Чтобы включить поддержку FOR UPDATE SKIP LOCKED, установите DatabaseFeatures.has_select_for_update_skip_locked = True.
  • Новый атрибут DatabaseFeatures.supports_index_column_ordering указывает, позволяет ли база данных определять порядок для столбцов в индексах. Значение по умолчанию True, и метод DatabaseIntrospection.get_constraints() должен включать 'orders' ключ в каждый из возвращаемых словарей со списком 'ASC' и/или 'DESC' значений, соответствующих упорядочению каждого столбца в индексе.
  • inspectdb больше не вызывает DatabaseIntrospection.get_indexes(), который является устаревшим. Пользовательские бэкенды баз данных должны убедиться, что все типы индексов возвращаются с помощью DatabaseIntrospection.get_constraints().
  • Переименовали функцию ignores_quoted_identifier_case в ignores_table_name_case, чтобы более точно отразить, как она используется.
  • Аргумент с ключевым словом name добавлен к методу DatabaseWrapper.create_cursor(self, name=None), чтобы позволить использовать курсоры на стороне сервера на бэкендах, которые это поддерживают.

Прекращена поддержка PostgreSQL 9.2 и PostGIS 2.0

Поддержка PostgreSQL 9.2 заканчивается в сентябре 2017 года. Как следствие, Django 1.11 устанавливает PostgreSQL 9.3 в качестве минимальной версии, которую он официально поддерживает.

Поддержка PostGIS 2.0 также удалена, поскольку PostgreSQL 9.2 является последней версией, поддерживающей его.

Кроме того, минимальная поддерживаемая версия psycopg2 увеличена с 2.4.5 до 2.5.4.

LiveServerTestCase привязка к нулевому порту

Вместо того чтобы брать диапазон портов и итеративно искать свободный порт, LiveServerTestCase привязывается к нулевому порту и полагается на то, что операционная система назначит свободный порт. Переменная окружения DJANGO_LIVE_TEST_SERVER_ADDRESS больше не используется, и поскольку она также больше не используется, опция manage.py test --liveserver удалена.

Если вам нужно привязать LiveServerTestCase к определенному порту, используйте атрибут port, добавленный в Django 1.11.2.

Защита от небезопасных перенаправлений в представлениях django.contrib.auth и i18n

LoginView, LogoutView (и устаревшие эквиваленты на основе функций) и set_language() защищают пользователей от перенаправления на URL, не относящиеся к HTTPS next, когда приложение работает через HTTPS.

QuerySet.get_or_create() и update_or_create() подтверждают аргументы

Чтобы предотвратить молчаливое прохождение опечаток, get_or_create() и update_or_create() проверяют, что их аргументы являются полями модели. Это должно быть обратно несовместимо только в том смысле, что это может выявить ошибку в вашем проекте.

pytz является необходимой зависимостью, а поддержка settings.TIME_ZONE = None удалена

Чтобы упростить работу Django с часовыми поясами, pytz теперь является обязательной зависимостью. Она автоматически устанавливается вместе с Django.

Поддержка settings.TIME_ZONE = None удалена, так как это поведение не часто используется и сомнительно полезно. Если вы хотите автоматически определять часовой пояс на основе системного часового пояса, вы можете использовать tzlocal:

from tzlocal import get_localzone

TIME_ZONE = get_localzone().zone

Это работает аналогично settings.TIME_ZONE = None, за исключением того, что оно также устанавливает os.environ['TZ']. Let us know если в каком-то случае вы обнаружите, что не можете адаптировать свой код для установки TIME_ZONE.

Изменения HTML в шаблонах администратора

<p class="help"> заменяется на тег <div>, что позволяет включать списки в текст справки.

Поля только для чтения обернуты в <div class="readonly">...</div> вместо <p>...</p>, что позволяет использовать любой HTML в качестве содержимого поля.

Изменения, связанные с внедрением рендеринга виджетов на основе шаблонов

Удалены некоторые недокументированные классы в django.forms.widgets:

  • SubWidget
  • RendererMixin, ChoiceFieldRenderer, RadioFieldRenderer, CheckboxFieldRenderer
  • ChoiceInput, RadioChoiceInput, CheckboxChoiceInput

Недокументированный метод Select.render_option() удален.

Метод Widget.format_output() удален. Вместо него используйте пользовательский шаблон виджета.

Некоторые значения виджетов, такие как опции <select>, теперь локализуются при settings.USE_L10N=True. Вы можете вернуться к старому поведению с помощью пользовательских шаблонов виджетов, которые используют тег шаблона localize для отключения локализации.

django.template.backends.django.Template.render() запрещает недиктовый контекст

Для совместимости с различными шаблонизаторами, django.template.backends.django.Template.render() (возвращаемый из высокоуровневых API загрузчика шаблонов, таких как loader.get_template()) должен получать словарь контекста, а не Context или RequestContext. Если вы передавали один из этих двух классов, передайте вместо него словарь - это обеспечивает обратную совместимость со старыми версиями Django.

Изменение состояния модели в операциях миграции

Для повышения скорости применения миграций рендеринг связанных моделей откладывается до операции, которой они нужны (например, RunPython). Если у вас есть пользовательская операция, которая работает с классами моделей или экземплярами моделей из аргумента from_state в database_forwards() или database_backwards(), вы должны отрисовать состояния модели с помощью метода clear_delayed_apps_cache(), как описано в writing your own migration operation.

Курсоры на стороне сервера в PostgreSQL

Изменение, заставляющее QuerySet.iterator() использовать серверные курсоры на PostgreSQL, не позволяет запустить Django с pgBouncer в режиме пула транзакций. Чтобы разрешить это, используйте параметр DISABLE_SERVER_SIDE_CURSORS (добавленный в Django 1.11.1) в DATABASES.

Более подробное обсуждение см. в разделе Объединение транзакций и курсоры на стороне сервера.

Разное

  • Если ни один элемент в ленте не имеет атрибута pubdate или updateddate, SyndicationFeed.latest_post_date() теперь возвращает текущую дату/время UTC, а не время без информации о часовом поясе.

  • Сбои CSRF регистрируются в журнале django.security.csrf вместо django.request.

  • Валидация ALLOWED_HOSTS больше не отключается при запуске тестов. Если ваше приложение включает тесты с пользовательскими именами хостов, вы должны включить эти имена хостов в ALLOWED_HOSTS. См. Тесты и несколько имен хостов.

  • Использование id внешнего ключа (например, 'field_id') в ModelAdmin.list_display отображает ID связанного объекта. Удалите суффикс _id, если вы хотите получить старое поведение строкового представления объекта.

  • В формах моделей CharField с null=True теперь сохраняет NULL для пустых значений вместо пустых строк.

  • В Oracle, Model.validate_unique() больше не проверяет пустые строки на уникальность, так как база данных интерпретирует значение как NULL.

  • Если вы создаете подкласс AbstractUser и переопределяете clean(), убедитесь, что он вызывает super(). BaseUserManager.normalize_email() вызывается в новом методе AbstractUser.clean(), чтобы нормализация применялась в таких случаях, как проверка формы модели.

  • EmailField и URLField больше не принимают аргумент в виде ключевого слова strip. Удалите его, потому что он не имеет эффекта в старых версиях Django, так как эти поля всегда отделяют пробелы.

  • Атрибуты checked и selected, отображаемые виджетами форм, теперь используют синтаксис HTML5 boolean, а не XHTML checked='checked' и selected='selected'.

  • RelatedManager.add(), remove(), clear() и set() теперь очищают кэш prefetch_related().

  • Чтобы предотвратить возможную потерю сохраненных настроек, setup_test_environment() теперь вызывает исключение, если вызывается во второй раз до вызова teardown_test_environment().

  • Недокументированный псевдоним DateTimeAwareJSONEncoder для DjangoJSONEncoder (переименованный в Django 1.0) удален.

  • Теперь cached template loader включается, если не указано OPTIONS['loaders'], а OPTIONS['debug'] - False (последний параметр по умолчанию имеет значение DEBUG). Это может быть обратно несовместимо, если у вас есть некоторые template tags that aren’t thread safe.

  • После выполнения команды migrate больше не появляется запрос на удаление устаревшего типа содержимого. Вместо нее используйте новую команду remove_stale_contenttypes.

  • Виджет администратора для IntegerField использует type="number", а не type="text".

  • Условные HTTP-заголовки теперь анализируются и сравниваются в соответствии со спецификацией RFC 7232 условных запросов, а не со старой RFC 2616.

  • patch_response_headers() больше не добавляет заголовок Last-Modified. Согласно RFC 7234#section-4.2.2, этот заголовок бесполезен наряду с другими заголовками кэширования, которые предоставляют явное время истечения срока действия, например, Expires или Cache-Control. UpdateCacheMiddleware и add_never_cache_headers() вызывают patch_response_headers() и поэтому также затронуты этим изменением.

  • В шаблонах администратора тег <p class="help"> заменен на тег <div>, что позволяет включать списки в текст справки.

  • ConditionalGetMiddleware больше не устанавливает заголовок Date, поскольку веб-серверы устанавливают этот заголовок. Он также больше не устанавливает заголовок Content-Length, поскольку теперь это делает CommonMiddleware.

    Если у вас есть промежуточное ПО, которое изменяет содержимое ответа и появляется перед CommonMiddleware в настройках MIDDLEWARE или MIDDLEWARE_CLASSES, вы должны изменить порядок своего промежуточного ПО так, чтобы ответы не изменялись после установки Content-Length, или чтобы промежуточное ПО, изменяющее ответ, сбросило заголовок Content-Length.

  • get_model() и get_models() теперь вызывают ошибку AppRegistryNotReady, если они вызваны до того, как модели всех приложений были загружены. Ранее они требовали загрузки только моделей целевого приложения и, таким образом, могли возвращать модели без всех установленных отношений. Если вам нужно старое поведение get_model(), установите аргумент require_ready в значение False.

  • Неиспользуемый атрибут BaseCommand.can_import_settings удаляется.

  • Недокументированное django.utils.functional.lazy_property удалено.

  • Для согласованности с запросами, не состоящими из нескольких частей, MultiPartParser.parse() теперь оставляет request.POST неизменным. Если вы изменяете QueryDict, то теперь вы должны сначала скопировать его, например, request.POST.copy().

  • Удалена поддержка cx_Oracle < 5.2.

  • Из команды shell удалена поддержка IPython < 1.0.

  • Подпись частного API Widget.build_attrs() изменена с extra_attrs=None, **kwargs на base_attrs, extra_attrs=None.

  • Файлоподобные объекты (например, StringIO и BytesIO), загруженные в ImageField с помощью тестового клиента, теперь требуют name атрибута со значением, которое проходит validate_image_file_extension валидатор. См. примечание в Client.post().

  • FileField теперь перемещает, а не копирует полученный файл. При настройках загрузки файлов по умолчанию файлы размером более FILE_UPLOAD_MAX_MEMORY_SIZE теперь имеют те же разрешения, что и временные файлы (часто 0o600), а не стандартный umask системы (часто 0o6644). Установите FILE_UPLOAD_PERMISSIONS, если вам нужно одинаковое разрешение независимо от размера файла.

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

Разное

  • Представления contrib.auth на основе функций login() и logout() устарели в пользу новых представлений LoginView и LogoutView на основе классов.
  • Неиспользуемый параметр extra_context contrib.auth.views.logout_then_login() является устаревшим.
  • Функциональные представления contrib.auth, password_change(), password_change_done(), password_reset(), password_reset_done(), password_reset_confirm() и password_reset_complete() устарели в пользу новых представлений на основе классов PasswordChangeView, PasswordChangeDoneView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView и PasswordResetCompleteView.
  • django.test.runner.setup_databases() перемещается в django.test.utils.setup_databases(). Старое расположение устарело.
  • django.utils.translation.string_concat() устарело в пользу django.utils.text.format_lazy(). string_concat(*strings) может быть заменено на format_lazy('{}' * len(strings), *strings).
  • Для бэкенда кэша PyLibMCCache передача параметров поведения pylibmc в качестве атрибутов верхнего уровня в OPTIONS устарела. Вместо этого задайте их под ключом behaviors внутри OPTIONS.
  • Параметр host в django.utils.http.is_safe_url() устарел в пользу нового параметра allowed_hosts.
  • Глушение исключений, возникающих при рендеринге тега шаблона {% include %}, устарело, поскольку такое поведение часто больше запутывает, чем помогает. В Django 2.1 исключение будет подниматься.
  • DatabaseIntrospection.get_indexes() устарело в пользу DatabaseIntrospection.get_constraints().
  • authenticate() теперь передает аргумент request методу authenticate() бэкендов аутентификации. Поддержка методов, которые не принимают request в качестве первого позиционного аргумента, будет удалена в Django 2.1.
  • Настройка USE_ETAGS устарела в пользу ConditionalGetMiddleware, которая теперь добавляет заголовок ETag к ответам независимо от настройки. CommonMiddleware и django.utils.cache.patch_response_headers() больше не будут устанавливать ETags, когда устаревание закончится.
  • Model._meta.has_auto_field устарело в пользу проверки наличия Model._meta.auto_field is not None.
  • Использование групп регулярных выражений с iLmsu# в url() является неактуальным. Единственной полезной группой является (?i) для URL, не чувствительных к регистру, однако URL, не чувствительные к регистру, не являются хорошей практикой, поскольку они создают множество записей, например, для поисковых систем. Альтернативным решением может быть создание handler404, который ищет в URL символы верхнего регистра и перенаправляет на эквивалент в нижнем регистре.
  • Аргумент renderer добавляется к методу Widget.render(). Методы, не принимающие этот аргумент, будут работать через период устаревания.
Вернуться на верх