Примечания к выпуску Django 4.0¶
7 декабря 2021 г.
Добро пожаловать в Джанго 4.0!
Эти примечания к выпуску охватывают новые функции, а также некоторые обратно несовместимые изменения, о которых вам следует знать при обновлении с Django 3.2 или более ранней версии. Мы начали процесс прекращения поддержки некоторых функций.
См. руководство Обновление Django до новой версии, если вы обновляете существующий проект.
Совместимость версий Python¶
Django 4.0 поддерживает Python 3.8, 3.9 и 3.10. Мы настоятельно рекомендуем и официально поддерживаем только последнюю версию каждой серии.
Серия Django 3.2.x является последней, поддерживающей Python 3.6 и 3.7.
Что нового в Джанго 4.0¶
zoneinfo реализация часового пояса по умолчанию¶
zoneinfo стандартной библиотеки Python теперь является реализацией часового пояса по умолчанию в Django.
Это следующий шаг в переходе от использования pytz к использованию zoneinfo. Django 3.2 позволял использовать часовые пояса, отличные от pytz. Django 4.0 делает Zoneinfo реализацией по умолчанию. Поддержка pytz устарела и будет удалена в Django 5.0.
zoneinfo является частью стандартной библиотеки Python версии Python 3.9. Пакет backports.zoneinfo автоматически устанавливается вместе с Django, если вы используете Python 3.8.
Переход на «zoneinfo» должен быть в значительной степени прозрачным. Выбор текущего часового пояса, преобразование экземпляров даты и времени в текущий часовой пояс в формах и шаблонах, а также операции с известными датами и временем в формате UTC не затрагиваются.
Однако, если вы работаете с часовыми поясами, отличными от UTC, и используете API-интерфейсы pytz,normalize() и localize(), возможно, с настройкой TIME_ZONE, вам потребуется провести аудит вашего кода, поскольку pytz иzoneinfo не полностью эквивалентны.
Чтобы дать время для такого аудита, переходная настройка USE_DEPRECATED_PYTZ позволяет продолжать использовать pytz в течение цикла выпуска 4.x. Этот параметр будет удален в Django 5.0.
Кроме того, пакет pytz_deprecation_shim, созданный автором Zoneinfo, может использоваться для облегчения перехода с pytz. Этот пакет предоставляет прокладки, которые помогут вам безопасно удалить pytz, а также содержит подробное руководство по миграции, показывающее, как перейти на новые API zoneinfo.
Использование pytz_deprecation_shim и переходной настройки USE_DEPRECATED_PYTZ рекомендуется, если вам нужен путь постепенного обновления.
Функциональные уникальные ограничения¶
Новый *expressions позиционный аргумент UniqueConstraint() позволяет создавать функциональные уникальные ограничения для выражений и функций базы данных. Например:
from django.db import models
from django.db.models import UniqueConstraint
from django.db.models.functions import Lower
class MyModel(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
class Meta:
constraints = [
UniqueConstraint(
Lower("first_name"),
Lower("last_name").desc(),
name="first_last_name_unique",
),
]
Функциональные уникальные ограничения добавляются в модели с помощью опции Meta.constraints.
scrypt хэшер паролей¶
Новый хэшер паролей :ref:scrypt <scrypt-usage>` более безопасен и рекомендуется по сравнению с PBKDF2. Однако это не вариант по умолчанию, поскольку для него требуется OpenSSL 1.1+ и больше памяти.
Серверная часть кэша Redis¶
Новый механизм кэширования django.core.cache.backends.redis.RedisCache обеспечивает встроенную поддержку кэширования с помощью Redis. redis-py 3.0.0 или выше. Для получения более подробной информации см. документацию по кэшированию с помощью Redis в Django.
Рендеринг форм на основе шаблонов¶
Forms, Formsets и ErrorList теперь отображаются с использованием механизма шаблонов для улучшения настройки. См. новые render(), get_context() и template_name для Form и formset rendering для Formset.
Минорные изменения¶
django.contrib.admin¶
Шаблон
admin/base.htmlтеперь имеет новый блокheader, который содержит заголовок сайта администрирования.Новый метод
ModelAdmin.get_formset_kwargs()позволяет настраивать аргументы ключевого слова, передаваемые конструктору набора форм.Боковая панель навигации теперь имеет панель быстрого фильтра.
В метод
AdminSite.each_context()добавляется новая контекстная переменнаяmodel, которая содержит класс модели для каждой модели.Новый атрибут
ModelAdmin.search_help_textпозволяет указать описательный текст для поля поиска.Атрибут
InlineModelAdmin.verbose_name_pluralтеперь заменяется наInlineModelAdmin.verbose_name+'s'.jQuery обновлен с версии 3.5.1 до 3.6.0.
django.contrib.admindocs¶
В документации администратора теперь разрешены сложные настройки, в которых
ROOT_URLCONFне является строкой.В разделе модели «admindocs» теперь отображаются кэшированные свойства.
django.contrib.auth¶
Число итераций по умолчанию для хэшера паролей PBKDF2 увеличено с 260 000 до 320 000.
Новый атрибут
LoginView.next_pageи методget_default_redirect_url()позволяют настроить перенаправление после входа в систему.
django.contrib.gis¶
Добавлена поддержка SpatiaLite 5.
GDALRasterтеперь позволяет создавать растры в любой виртуальной файловой системе GDAL.Новый класс
GISModelAdminпозволяет настраивать виджет, используемый дляGeometryField. Это рекомендуется вместо устаревшихGeoModelAdminиOSMGeoAdmin.
django.contrib.postgres¶
Серверная часть PostgreSQL теперь поддерживает подключение по имени службы. Дополнительную информацию см. в разделе Настройки подключения PostgreSQL.
Новая операция
AddConstraintNotValidпозволяет создавать проверочные ограничения в PostgreSQL без проверки того, что все существующие строки удовлетворяют новому ограничению.Новая операция
ValidateConstraintпозволяет проверять проверочные ограничения, которые были созданы с помощьюAddConstraintNotValidв PostgreSQL.Новое выражение
ArraySubquery()позволяет использовать подзапросы для создания списков значений в PostgreSQL.Новый поиск
trigram_word_similarи выраженияTrigramWordDistance()иTrigramWordSimilarity()позволяют использовать сходство слов триграммы.
django.contrib.staticfiles¶
ManifestStaticFilesStorageтеперь заменяет пути к ссылкам на исходную карту JavaScript их хешированными аналогами.Новый аргумент
manifest_storageдляManifestFilesMixinиManifestStaticFilesStorageпозволяет настроить хранилище файлов манифеста.
Кэш¶
Новый асинхронный API для django.core.cache.backends.base.BaseCache начинает процесс создания асинхронно-совместимых серверных частей кэша. Все новые асинхронные методы имеют имена с префиксом
a, например:aadd(),aget(),aset(),aget_or_set()илиadelete_many().В дальнейшем префикс a будет использоваться для асинхронных вариантов методов.
CSRF¶
Защита CSRF теперь обращается к заголовку Origin, если он присутствует. Чтобы облегчить это, некоторые изменения в настройке
CSRF_TRUSTED_ORIGINSнеобходимы.
Формы¶
ModelChoiceFieldтеперь включает указанное значение в аргументparamsвозникшегоValidationErrorдля сообщения об ошибкеinvalid_choice. Это позволяет пользовательским сообщениям об ошибках использовать заполнитель%(value)s.BaseFormSetтеперь отображает ошибки, не относящиеся к форме, с помощью дополнительного классаnonform, чтобы помочь отличить их от ошибок, специфичных для формы.BaseFormSetтеперь позволяет настраивать виджет, используемый при удалении форм черезcan_delete, устанавливая или переопределяя атрибутdeletion_widgetget_deletion_widget()метод.
Интернационализация¶
Добавлена поддержка и переводы на малайский язык.
Общие представления¶
DeleteViewтеперь используетFormMixin, что позволяет вам предоставить подклассForm, например, с флажком для подтверждения удаления. Кроме того, это позволяетDeleteViewработать сdjango.contrib.messages.views.SuccessMessageMixin.В соответствии с FormMixin удаление объекта для запросов POST обрабатывается в form_valid(). Пользовательскую логику удаления в обработчиках
delete()следует переместить вform_valid()или в общий вспомогательный метод, если необходимо.
Ведение журнала¶
Псевдоним базы данных, используемый в вызове SQL, теперь передается в качестве дополнительного контекста вместе с каждым сообщением в регистратор django-db-logger.
Команды управления¶
Команда управления
runserverтеперь поддерживает опцию--skip-checks.В PostgreSQL
dbshellтеперь поддерживает указание файла паролей.Команда
shellтеперь учитываетsys.__interactivehook__при запуске. Это позволяет загружать историю оболочки между интерактивными сеансами. Как следствие,readlineбольше не загружается при работе в изолированном режиме.Новый атрибут
BaseCommand.suppressed_base_argumentsпозволяет подавлять неподдерживаемые параметры команды по умолчанию в выводе справки.Новые параметры
startapp --excludeиstartproject --excludeпозволяют исключать каталоги из шаблона.
Модели¶
Новый метод
QuerySet.contains(obj)возвращает, содержит ли набор запросов данный объект. Это попытка выполнить запрос самым простым и быстрым способом.Новый аргумент
precisionфункции базы данныхRound()позволяет указать количество десятичных знаков после округления.QuerySet.bulk_create()теперь устанавливает первичный ключ для объектов при использовании SQLite 3.35+.DurationFieldтеперь поддерживает умножение и деление на скалярные значения в SQLite.QuerySet.bulk_update()теперь возвращает количество обновленных объектов.Новый атрибут
Expression.empty_result_set_valueпозволяет указать возвращаемое значение, когда функция используется с пустым набором результатов.Аргумент
skip_lockedQuerySet.select_for_update()теперь разрешен в MariaDB 10.6+.Lookupвыражения теперь можно использовать в аннотацияхQuerySet, агрегатах и непосредственно в фильтрах.Новый аргумент default для встроенных агрегатов позволяет указать значение, возвращаемое, когда набор запросов (или группа) не содержит записей, а не
Нет.
Запросы и ответы¶
SecurityMiddlewareтеперь добавляет заголовок Cross-Origin Opener Policy со значением'same-origin', чтобы предотвратить использование одного и того же контекста просмотра всплывающими окнами из разных источников. Вы можете предотвратить добавление этого заголовка, установив для параметраSECURE_CROSS_ORIGIN_OPENER_POLICYзначениеNone.
Сигналы¶
Новый аргумент
stdoutдля сигналовpre_migrate()иpost_migrate()позволяет перенаправить вывод в потокоподобный объект. Его следует отдавать предпочтение передsys.stdoutиprint()при выдаче подробного вывода, чтобы обеспечить правильный захват при тестировании.
Шаблоны¶
Фильтр шаблонов
floatformatтеперь позволяет использовать суффиксuдля принудительного отключения локализации.
Тесты¶
Новый аргумент
serialized_aliasesdjango.test.utils.setup_databases()определяет, какие :setting:``DATABASES` тестовые базы данных псевдонимов должны иметь сериализацию своего состояния, чтобы разрешить использование функции serialized_rollback.Опция
test --bufferтеперь поддерживает параллельные тесты.Новый аргумент
loggerдляDiscoverRunnerпозволяет использовать Python logger для ведения журнала.Новый метод
DiscoverRunner.log()обеспечивает способ регистрации сообщений, который используетDiscoverRunner.loggerили выводит на консоль, если он не установлен.DiscoverRunnerтеперь может выполнять тесты в случайном порядке, используя опциюtest --shuffle.Опция
test --parallelтеперь поддерживает значениеautoдля запуска одного тестового процесса для каждого ядра процессора.TestCase.captureOnCommitCallbacks()теперь фиксирует новые обратные вызовы, добавленные во время выполнения обратных вызововtransaction.on_commit().
Изменения обратной несовместимости в версии 4.0¶
Серверный API базы данных¶
В этом разделе описаны изменения, которые могут потребоваться в сторонних базах данных.
Методы DatabaseOperations.year_lookup_bounds_for_date_field() иyear_lookup_bounds_for_datetime_field() теперь принимают необязательный аргумент iso_year для поддержки границ для лет с нумерацией недель ISO-8601.
Вторым аргументом методов
DatabaseSchemaEditor._unique_sql()и_create_unique_sql()теперь являютсяполявместостолбцы.
django.contrib.gis¶
Поддержка PostGIS 2.3 удалена.
Поддержка GDAL 2.0 и GEOS 3.5 удалена.
Прекращена поддержка PostgreSQL 9.6.¶
Поддержка исходной версии PostgreSQL 9.6 заканчивается в ноябре 2021 года. Django 4.0 поддерживает PostgreSQL 10 и выше.
Кроме того, минимальная поддерживаемая версия psycopg2 увеличена с 2.5.4 до 2.8.4, поскольку psycopg2 2.8.4 является первой версией, поддерживающей Python 3.8.
Прекращена поддержка Oracle 12.2 и 18c.¶
Восходящая поддержка Oracle 12.2 заканчивается в марте 2022 года, а Oracle 18c — в июне 2021 года. Django 3.2 будет поддерживаться до апреля 2024 года. Django 4.0 официально поддерживает Oracle 19c.
CSRF_TRUSTED_ORIGINS изменения¶
Изменение формата¶
Значения в настройке CSRF_TRUSTED_ORIGINS должны включать схему (например, 'http://' или 'https://', а не только имя хоста.
Кроме того, значения, начинающиеся с точки, теперь также должны включать звездочку перед точкой. Например, измените '.example.com' на 'https://*.example.com'.
Проверка системы выявляет все необходимые изменения.
Теперь может потребоваться его настройка.¶
Поскольку защита CSRF теперь обращается к заголовку Origin, вам может потребоваться установить CSRF_TRUSTED_ORIGINS, особенно если вы разрешаете запросы от поддоменов, задав для CSRF_COOKIE_DOMAIN (или SESSION_COOKIE_DOMAIN, если CSRF_USE_SESSIONS включен) значение, начинающееся с точка.
SecurityMiddleware больше не устанавливает заголовок X-XSS-Protection.¶
SecurityMiddleware больше не устанавливает заголовок X-XSS-Protection, если для параметра SECURE_BROWSER_XSS_FILTER установлено значение True. Настройка удалена.
Большинство современных браузеров не учитывают HTTP-заголовок X-XSS-Protection. Вы можете использовать Content-Security-Policy, не разрешая вместо этого сценарии unsafe-inline.
Если вы хотите поддерживать устаревшие браузеры и устанавливать заголовок, используйте эту строку в пользовательском промежуточном программном обеспечении:
response.headers.setdefault("X-XSS-Protection", "1; mode=block")
Изменения автодетектора миграций¶
Автодетектор миграций теперь использует состояния модели вместо классов модели. Кроме того, операции миграции для полей «ForeignKey» и «ManyToManyField» больше не указывают атрибуты, которые не были переданы в поля во время инициализации.
В качестве побочного эффекта запуск makemigrations может в некоторых случаях генерировать неактивные операции AlterField для полей ManyToManyField и ForeignKey.
Изменения DeleteView¶
DeleteView теперь использует FormMixin для обработки POST-запросов. Как следствие, любая пользовательская логика удаления в обработчиках delete() должна быть перенесена в form_valid() или в общий вспомогательный метод, если это необходимо.
Изменения в схеме именования таблиц и столбцов в Oracle¶
Django 4.0 случайно изменил схему именования таблиц и столбцов в Oracle. Это вызывает ошибки для моделей и полей с именами длиной более 30 символов. К сожалению, необходимо переименовать некоторые таблицы и столбцы Oracle. Используйте сценарий обновления в 33789 для создания операторов RENAME для изменения схемы именования.
Разнообразный¶
Поддержка
cx_Oracle< 7.0 удалена.Чтобы разрешить обслуживание сайта Django по подпути без изменения значения
STATIC_URL, из этого параметра (теперь'static/') в шаблонеstartprojectпо умолчанию удаляется начальная косая черта.Метод
AdminSiteдля представленияindexадминистратора больше не украшаетсяnever_cacheпри прямом доступе, а не через рекомендуемое свойство AdminSite.urls или метод AdminSite.get_urls().Неподдерживаемые операции с фрагментированным набором запросов теперь вызывают ошибку TypeError вместо AssertionError.
Недокументированная функция django.test.runner.reorder_suite() переименована в reorder_tests(). Теперь он принимает итерацию тестов, а не набор тестов, и возвращает итератор тестов.
Вызов FileSystemStorage.delete() с пустым именем теперь вызывает ValueError вместо AssertionError.
Вызов EmailMultiAlternatives.attach_alternative() или EmailMessage.attach() с недопустимыми аргументами content или mimetype теперь вызывает ValueError вместо AssertionError.
assertHTMLEqual()больше не рассматривает нелогический атрибут без значения, равного атрибуту с тем же именем и значением.Тесты, которые не загружаются, например, из-за синтаксических ошибок, теперь всегда совпадают при использовании
test --tag.Недокументированная функция django.contrib.admin.utils.lookup_needs_distinct() переименована вlookup_spawns_duulates().
Недокументированный метод HttpRequest.get_raw_uri() удален. Подходящей альтернативой может быть метод
HttpRequest.build_absolute_uri().Аргумент
objectнедокументированных методовModelAdmin.log_addition(),log_change()иlog_deletion()переименован вobj.RssFeed,Atom1Feedи их подклассы теперь выдают элементы без содержимого в виде самозакрывающихся тегов.NodeList.render()больше не преобразует вывод методаrender()для отдельных узлов в строку.Node.render()всегда должен возвращать строку, как описано в документации.Свойствоwhere_class`` django.db.models.sql.query.Query`` и аргумент
where_classчастного методаget_extra_restriction()ForeignObjectиForeignObjectRelудалены. При необходимости вместо этого инициализируйте django.db.models.sql.where.WhereNode.Аргумент filter_clause недокументированного метода Query.add_filter() заменяется двумя позиционными аргументами filter_lhs и filter_rhs.
CsrfViewMiddlewareтеперь используетrequest.META['CSRF_COOKIE_NEEDS_UPDATE']вместоrequest.META['CSRF_COOKIE_USED'],request.csrf_cookie_needs_reset, иresponse.csrf_cookie_setдля отслеживания того, следует ли отправлять файл cookie CSRF. Это недокументированный частный API.Недокументированная константа TRANSLATOR_COMMENT_MARK перемещена из django.template.base в django.utils.translation.template.
Аргумент
real_appsнедокументированного методаdjango.db.migrations.state.ProjectState.__init__()теперь должен быть установлен, если он указан.Виджеты
RadioSelectиCheckboxSelectMultipleтеперь отображаются в тегах<div>, поэтому программы чтения с экрана объявляют их более кратко. Если вам нужно предыдущее поведение, переопределите шаблон виджета соответствующим шаблоном из Django 3.2.Фильтр шаблона
floatformatбольше не зависит от настройкиUSE_L10Nи всегда возвращает локализованный вывод. Используйте суффиксu, чтобы отключить локализацию.Значение по умолчанию параметра USE_L10N изменено на True. Дополнительную информацию см. в разделе «Локализация <use_l10n_deprecation>» выше.
В рамках move tozoneinfo
django.utils.timezone.utcзаменяется на псевдонимdatetime.timezone.utc.Минимальная поддерживаемая версия asgiref увеличена с 3.3.2 до 3.4.1.
Функции, устаревшие в версии 4.0¶
Использование часовых поясов pytz¶
В рамках перехода на Zoneinfo <whats-new-4.0> использование часовых поясов pytz устарело.
Соответственно, аргументы is_dst для следующих команд также считаются устаревшими:
Поддержка использования pytz будет удалена в Django 5.0.
Поддержка часовых поясов¶
Чтобы следовать передовой практике, значение по умолчанию параметра USE_TZ изменится с False на True, а поддержка часовых поясов будет включена по умолчанию в Django 5.0.
Обратите внимание, что файл settings.py по умолчанию, созданный django-admin startproject, включает USE_TZ = True, начиная с Django 1.4.
Вы можете установить для USE_TZ значение False в настройках вашего проекта, прежде чем отказаться от участия.
Локализация¶
Чтобы следовать передовой практике, значение по умолчанию параметра USE_L10N изменено с False на True.
Более того, USE_L10N устарел с этой версии. Начиная с Django 5.0, по умолчанию любая дата или число, отображаемые Django, будут локализованы.
Тег {% localize %} и фильтры localize/ unlocalize по-прежнему будут учитываться Django.
Разнообразный¶
Тестовая настройка
SERIALIZEустарела, поскольку ее можно получить изdatabasesс включенной опцией serialized_rollback.Недокументированный модуль django.utils.baseconv устарел.
Недокументированный модуль django.utils.datetime_safe устарел.
Протокол карты сайта по умолчанию для карт сайта, созданных вне контекста запроса, изменится с «http» на «https» в Django 5.0.
Аргумент
extra_testsдляDiscoverRunner.build_suite()иDiscoverRunner.run_tests()устарел.Агрегаты
ArrayAgg,JSONBAggиStringAggбудут возвращатьNone, если вместо[],[], нет строк, и''соответственно в Django 5.0. Если вам нужно предыдущее поведение, явно установите дляdefaultзначениеValue([]),Value('[]')илиValue('').Классы django.contrib.gis.admin.GeoModelAdmin и OSMGeoAdmin устарели. Вместо этого используйте
ModelAdminиGISModelAdmin.Поскольку рендеринг формы теперь использует механизм шаблонов, недокументированный вспомогательный метод BaseForm._html_output() считается устаревшим.
Возможность возвращать str из ErrorList и ErrorDict устарела. Ожидается, что эти методы возвращают SafeString.
Функции удалены в версии 4.0¶
Эти функции достигли конца цикла устаревания и удалены в Django 4.0.
См. Функции, устаревшие в версии 3.0 для получения подробной информации об этих изменениях, в том числе о том, как прекратить использование этих функций.
django.utils.http.urlquote(),urlquote_plus(),urlunquote()иurlunquote_plus()удалены.django.utils.encoding.force_text()иsmart_text()удалены.django.utils.translation.ugettext(),ugettext_lazy(),ugettext_noop(),ungettext()иungettext_lazy()удалены.django.views.i18n.set_language()не устанавливает язык пользователя вrequest.session(ключ_language).alias=Noneтребуется в сигнатуре подклассовdjango.db.models.Expression.get_group_by_cols().django.utils.text.unescape_entities()удален.django.utils.http.is_safe_url()удален.
См. Функции, устаревшие в версии 3.1 для получения подробной информации об этих изменениях, в том числе о том, как прекратить использование этих функций.
Параметр PASSWORD_RESET_TIMEOUT_DAYS удален.
Поиск
isnullбольше не позволяет использовать нелогические значения в правой части.Класс исключений django.db.models.query_utils.InvalidQuery удален.
Точка входа django-admin.py удалена.
Метод HttpRequest.is_ajax() удален.
Поддержка формата кодирования значений cookie до версии Django 3.1, используемого django.contrib.messages.storage.cookie.CookieStorage, удалена.
Поддержка токенов сброса пароля до Django 3.1 на сайте администратора (которые используют алгоритм хеширования SHA-1) удалена.
Поддержка формата кодирования сеансов до Django 3.1 удалена.
Поддержка подписей
django.core.signing.Signer(закодированных с помощью алгоритма SHA-1) до Django 3.1 удалена.Поддержка подписей django.core.signing.dumps() (закодированных с помощью алгоритма SHA-1) до версии Django 3.1 в django.core.signing.loads() удалена.
Поддержка пользовательских сеансов до Django 3.1 (которые используют алгоритм SHA-1) удалена.
Аргумент get_response для django.utils.deprecation.MiddlewareMixin.__init__() является обязательным и не принимает None.
Аргументproviding_args для django.dispatch.Signal удален.
Аргумент length для django.utils.crypto.get_random_string() является обязательным.
Сообщение list для ModelMultipleChoiceField удалено.
Поддержка передачи псевдонимов необработанных столбцов в QuerySet.order_by() удалена.
Поле модели NullBooleanField удалено, за исключением поддержки исторических миграций.
django.conf.urls.url()удален.Поле модели django.contrib.postgres.fields.JSONField удалено, за исключением поддержки исторических миграций.
django.contrib.postgres.fields.jsonb.KeyTransformиdjango.contrib.postgres.fields.jsonb.KeyTextTransformудалены.django.contrib.postgres.forms.JSONFieldудален.Теги шаблонов
{% ifequal %}и{% ifnotequal %}удалены.Переходный параметр DEFAULT_HASHING_ALGORITHM удален.