Примечания к выпуску Django 4.2 - ПОД РАЗРАБОТКОЙ

Ожидается в апреле 2023 года

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

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

См. руководство How to upgrade Django to a newer version, если вы обновляете существующий проект.

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

Django 4.2 поддерживает Python 3.8, 3.9, 3.10 и 3.11. Мы настоятельно рекомендуем и официально поддерживаем только последний выпуск каждой серии.

Что нового в Django 4.2

Поддержка Psycopg 3

Django теперь поддерживает psycopg версии 3.1 или выше. Чтобы обновить ваш код, установите psycopg library, вам не нужно менять ENGINE, так как django.db.backends.postgresql поддерживает обе библиотеки.

Поддержка psycopg2, вероятно, будет устаревшей и удалена в какой-то момент в будущем.

Устранение последствий атаки BREACH

GZipMiddleware теперь включает смягчение последствий атаки BREACH. Он добавляет до 100 случайных байтов в gzip-ответы, чтобы затруднить атаки BREACH. Подробнее о технике смягчения атаки читайте в Heal The Breach (HTB) paper.

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

django.contrib.admin

  • Светлая или темная цветовая тема администратора теперь может быть переключена в пользовательском интерфейсе, а также может быть установлена в соответствии с системными настройками.
  • Стек шрифтов администратора теперь предпочитает системные шрифты пользовательского интерфейса и больше не требует загрузки шрифтов. Кроме того, доступны переменные CSS для более удобного переопределения семейств шрифтов по умолчанию.
  • Шаблон admin/delete_confirmation.html теперь имеет несколько дополнительных блоков и скриптовых крючков для облегчения настройки.
  • Выбранные опции виджетов filter_horizontal и filter_vertical теперь можно фильтровать.
  • В шаблоне admin/base.html теперь есть новый блок nav-breadcrumbs, который содержит навигационный ориентир и блок breadcrumbs.
  • ModelAdmin.list_editable теперь использует атомарные транзакции при внесении правок.

django.contrib.auth

  • Число итераций по умолчанию для хешера паролей PBKDF2 увеличено с 390 000 до 480 000.
  • UserCreationForm теперь сохраняет поля формы «многие-ко-многим» для пользовательской модели пользователя.

django.contrib.gis

  • GeoJSON serializer теперь выводит ключ id для сериализованных функций, который по умолчанию равен первичному ключу объектов.
  • Класс GDALRaster теперь поддерживает pathlib.Path.
  • Класс GeoIP2 теперь поддерживает файлы .mmdb, загруженные с DB-IP.
  • Виджет шаблона OpenLayers больше не включает встроенный CSS (что также удаляет прежний блок map_css), чтобы лучше соответствовать строгой политике безопасности содержимого.

django.contrib.postgres

django.contrib.sitemaps

  • Новый метод Sitemap.get_languages_for_item() позволяет настроить список языков, для которых отображается элемент.

django.contrib.staticfiles

  • ManifestStaticFilesStorage теперь заменяет пути к модулям JavaScript в операторах import и export их хэшированными аналогами.

Кэш

CSRF

Декораторы

Електронна пошта

Отчеты об ошибках

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

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

Формы

  • ModelForm теперь принимает новую опцию Meta formfield_callback для настройки полей формы.
  • modelform_factory() теперь уважает атрибут formfield_callback в form в Meta.
  • Сеансовые куки теперь рассматриваются как учетные данные и поэтому скрываются, а в отчетах об ошибках заменяются звездочками (**********).

Общие представления

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

  • Добавлена поддержка и переводы для центральнокурдского языка (Sorani).
  • LocaleMiddleware теперь учитывает язык из запроса, когда i18n_patterns() используется с аргументом prefix_default_language, установленным в False.

Ведение журнала

  • Регистратор django.db.backends теперь регистрирует запросы управления транзакциями (BEGIN, COMMIT и ROLLBACK) на уровне DEBUG.

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

  • Команда makemessages теперь поддерживает локали с частными подтегами, такими как nl_NL-x-informal.
  • Новая опция makemigrations --update объединяет изменения модели в последнюю миграцию и оптимизирует результирующие операции.

Миграции

  • Миграции теперь поддерживают сериализацию объектов enum.Flag.

Модели

  • QuerySet теперь широко поддерживает фильтрацию против Функции окна за исключением дизъюнктивного поиска фильтра против оконных функций при выполнении агрегации.
  • prefetch_related() теперь поддерживает Prefetch объекты с нарезанными кверисетами.
  • Registering lookups на экземплярах Field теперь поддерживается.
  • Новый аргумент robust для on_commit() позволяет выполнять действия, которые могут завершиться неудачей после успешной фиксации транзакции базы данных.
  • Новое выражение KT() представляет текстовое значение ключа, индекса или преобразования пути JSONField.
  • Now теперь поддерживает микросекундную точность в MySQL и миллисекундную точность в SQLite.
  • Выражения F(), выводящие BooleanField, теперь можно отрицать с помощью ~F() (оператор инверсии).
  • Model теперь предоставляет асинхронные версии некоторых методов, использующих базу данных, с использованием префикса a: adelete(), arefresh_from_db() и asave().
  • Менеджеры Related теперь предоставляют асинхронные версии методов, которые изменяют набор связанных объектов, используя префикс a: aadd(), aclear(), aremove() и aset().

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

  • StreamingHttpResponse теперь поддерживает асинхронные итераторы, когда Django обслуживается через ASGI.

Безопасность

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

Сигналы

Шаблоны

Тесты

  • Опция test --debug-sql теперь форматирует SQL-запросы с помощью sqlparse.

  • Классы RequestFactory, AsyncRequestFactory, Client и AsyncClient теперь поддерживают параметр headers, который принимает словарь имен и значений заголовков. Это позволяет использовать более естественный синтаксис для объявления заголовков.

    # Before:
    self.client.get("/home/", HTTP_ACCEPT_LANGUAGE="fr")
    await self.async_client.get("/home/", ACCEPT_LANGUAGE="fr")
    
    # After:
    self.client.get("/home/", headers={"accept-language": "fr"})
    await self.async_client.get("/home/", headers={"accept-language": "fr"})
    

URL-адреса

Утилиты

  • Новый параметр encoder для функции django.utils.html.json_script() позволяет настроить класс кодировщика JSON.
  • Частная внутренняя вендорная копия urllib.parse.urlsplit() теперь отделяет '\r', '\n' и '\t' (см. CVE-2022-0391 и bpo-43882). Это сделано для защиты проектов, которые могут неправильно использовать внутреннюю функцию url_has_allowed_host_and_scheme() вместо того, чтобы использовать одну из документированных функций для обработки перенаправлений URL. Функции Django не были затронуты.
  • Новая функция django.utils.http.content_disposition_header() возвращает значение заголовка HTTP Content-Disposition, указанное в RFC 6266.

Валидаторы

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

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

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

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

  • DatabaseFeatures.allows_group_by_pk удалено, поскольку оно оставалось только для того, чтобы приспособить расширение MySQL, которое было вытеснено надлежащим функциональным обнаружением зависимостей в MySQL 5.7.15. Обратите внимание, что DatabaseFeatures.allows_group_by_selected_pks все еще поддерживается и должен быть включен, если ваш бэкенд поддерживает обнаружение функциональных зависимостей в предложениях GROUP BY, как указано в стандарте SQL:1999.

Прекращена поддержка MariaDB 10.3

Поддержка MariaDB 10.3 заканчивается в мае 2023 года. Django 4.2 поддерживает MariaDB 10.4 и выше.

Прекращена поддержка MySQL 5.7

Поддержка MySQL 5.7 заканчивается в октябре 2023 года. Django 4.2 поддерживает MySQL 8 и выше.

Прекращена поддержка PostgreSQL 11

Поддержка PostgreSQL 11 заканчивается в ноябре 2023 года. Django 4.2 поддерживает PostgreSQL 12 и выше.

Установка update_fields в Model.save() теперь может потребоваться

Чтобы избежать обновления ненужных столбцов, QuerySet.update_or_create() теперь передает update_fields в вызовы Model.save(). Как следствие, любые поля, измененные в пользовательских методах save(), должны быть добавлены в аргумент ключевого слова update_fields перед вызовом super(). Более подробную информацию см. в разделе Переопределение методов модели.

Разное

  • Недокументированные SimpleTemplateResponse.rendering_attrs и TemplateResponse.rendering_attrs переименованы в non_picklable_attrs.
  • Недокументированная функция django.http.multipartparser.parse_header() удалена. Вместо нее используйте django.utils.http.parse_header_parameters().
  • Результат {% blocktranslate asvar %} теперь помечен как безопасный для (HTML) вывода.
  • HTML-атрибут autofocus в окне поиска администратора удален, так как он может сбивать с толку читателей экрана.
  • The makemigrations --check option no longer creates missing migration files.
  • Аргумент alias для Expression.get_group_by_cols() удаляется.
  • T
  • T
  • T
  • T
  • <
  • T

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

Опция index_together устарела в пользу indexes.

Опция Meta.index_together устарела в пользу опции indexes.

Миграция существующих index_together должна обрабатываться как миграция. Например:

class Author(models.Model):
    rank = models.IntegerField()
    name = models.CharField(max_length=30)

    class Meta:
        index_together = [["rank", "name"]]

Должно стать:

class Author(models.Model):
    rank = models.IntegerField()
    name = models.CharField(max_length=30)

    class Meta:
        indexes = [models.Index(fields=["rank", "name"])]

Выполнение команды makemigrations создаст миграцию, содержащую операцию RenameIndex, которая переименует существующий индекс.

Операция миграции AlterIndexTogether теперь официально поддерживается только для файлов миграции, созданных до версии Django 4.2. По причинам обратной совместимости, она все еще является частью публичного API, и нет планов по ее обесцениванию или удалению, но она не должна использоваться для новых миграций. Вместо этого используйте операции AddIndex и RemoveIndex.

Минимальная поддерживаемая версия JSONField увеличена с 3.5.2 до 3.6.0.

JSONField и связанные с ним поиск и агрегаты использовали возможность передачи строковых литералов в кодировке JSON, что вызывало неоднозначность в отношении того, были ли строковые литералы уже закодированы с точки зрения бэкенда базы данных.

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

Код, который используется для передачи строковых литералов в кодировке JSON:

Document.objects.bulk_create(
    Document(data=Value("null")),
    Document(data=Value("[]")),
    Document(data=Value('"foo-bar"')),
)
Document.objects.annotate(
    JSONBAgg("field", default=Value('[]')),
)

Должно стать:

Document.objects.bulk_create(
    Document(data=Value(None, JSONField())),
    Document(data=[]),
    Document(data="foo-bar"),
)
Document.objects.annotate(
    JSONBAgg("field", default=[]),
)

Начиная с Django 5.1+ строковые литералы будут неявно интерпретироваться как строковые литералы JSON.

Разное

  • Метод BaseUserManager.make_random_password() является устаревшим. См. recipes and best practices об использовании модуля Python secrets для генерации паролей.

  • Шаблонный фильтр length_is устарел в пользу length и оператора == внутри тега {% if %}. Например

    {% if value|length == 4 %}{% endif %}
    {% if value|length == 4 %}True{% else %}False{% endif %}
    

    вместо:

    {% if value|length_is:4 %}{% endif %}
    {{ value|length_is:4 }}
    
  • django.contrib.auth.hashers.SHA1PasswordHasher, django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher и django.contrib.auth.hashers.UnsaltedMD5PasswordHasher устарели.

  • django.contrib.postgres.fields.CICharField устарел в пользу CharField(db_collation="…") с нечувствительной к регистру недетерминированной коллизией.

  • django.contrib.postgres.fields.CIEmailField устарел в пользу EmailField(db_collation="…") с нечувствительной к регистру недетерминированной коллизией.

  • django.contrib.postgres.fields.CITextField устарел в пользу TextField(db_collation="…") с нечувствительной к регистру недетерминированной коллизией.

  • Миксин django.contrib.postgres.fields.CIText устарел.

  • Атрибуты map_height и map_width в BaseGeometryWidget устарели, вместо них используйте CSS для определения размера виджетов карты.

  • SimpleTestCase.assertFormsetError() устарел в пользу assertFormSetError().

  • TransactionTestCase.assertQuerysetEqual() устарел в пользу assertQuerySetEqual().

  • Передача позиционных аргументов в Signer и TimestampSigner устарела в пользу аргументов, содержащих только ключевые слова.

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