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

Примечания к выпуску 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

Формы

  • ModelChoiceField теперь включает указанное значение в аргумент params возникшего ValidationError для сообщения об ошибке invalid_choice. Это позволяет пользовательским сообщениям об ошибках использовать заполнитель %(value)s.

  • BaseFormSet теперь отображает ошибки, не относящиеся к форме, с помощью дополнительного класса nonform, чтобы помочь отличить их от ошибок, специфичных для формы.

  • BaseFormSet теперь позволяет настраивать виджет, используемый при удалении форм через can_delete, устанавливая или переопределяя атрибут deletion_widget get_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_locked QuerySet.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_aliases django.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 удален.

Back to Top