Новые функции и изменения в Django 4.2: примечания к выпуску
Django

Новые функции и изменения в Django 4.2: примечания к выпуску

Razilator

Django 4.2 был выпущен с новыми функциями и изменениями, которые включают поддержку библиотеки Psycopg 3 и усиленную защиту от атаки BREACH. Однако, также есть обратно несовместимые изменения, которые нужно учитывать при обновлении с более ранних версий.

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

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

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

В Django 4.2 теперь возможна работа с psycopg версии 3.1 и выше. Для обновления вашего кода необходимо установить библиотеку psycopg, но не требуется изменять ENGINE, поскольку django.db.backends.postgresql поддерживает обе библиотеки.

Возможно, поддержка psycopg2 будет устаревшей и в будущем ее удаление будет осуществлено.

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

В Django 4.2 было добавлено смягчение последствий атаки BREACH в GZipMiddleware. Теперь при отправке gzip-ответов он добавляет до 100 случайных байтов, чтобы затруднить возможные атаки. Дополнительную информацию о технике смягчения атаки можно найти в статье "Heal The Breach (HTB)".

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

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

django.contrib.postgres

  • Модуль trigram_strict_word_similar, а также выражения TrigramStrictWordSimilarity() и TrigramStrictWordDistance() добавлены для поддержки триграммного строгого сравнения слов при поиске.
  • Теперь метод arrayfield.overlap поддерживает QuerySet.values() и values_list() в качестве правой части.

django.contrib.sitemaps

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

django.contrib.staticfiles

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

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

  • Страница отладки теперь показывает exception notes и fine-grained error locations на Python 3.11+.

Формы

  • Теперь в ModelForm доступна новая опция Meta formfield_callback для индивидуальной настройки полей формы. -Функция modelform_factory() теперь учитывает атрибут formfield_callback в форме 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-объекты с нарезанными кверисетами.
  • Добавлена поддержка регистрации lookups на экземплярах Field.
  • Добавлен новый аргумент "robust" для on_commit(), позволяющий выполнить действия, которые могут завершиться неудачей после успешной фиксации транзакции базы данных.
  • Добавлено новое выражение KT(), которое представляет текстовое значение ключа, индекса или преобразования пути JSONField.
  • Now теперь поддерживает микросекундную точность в MySQL и миллисекундную точность в SQLite.
  • Выражения F(), выводящие BooleanField, теперь можно отрицать с помощью оператора инверсии ~F().
  • Модель теперь предоставляет асинхронные версии некоторых методов, использующих базу данных, с использованием префикса "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"})

Утилиты

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

Валидаторы

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

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

  • Изменения, несовместимые с обратными изменениями, в Django 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, MySQL 5.7 и PostgreSQL 11 прекращена в Django 4.2, и вместо этого поддерживаются MariaDB 10.4 и выше, MySQL 8 и выше, и 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.
  • Атрибут autofocus в окне поиска администратора был удален, так как он может быть неудобен для пользователей, использующих читалки экрана. Опция --check в команде makemigrations теперь не создает отсутствующие файлы миграций.
  • Аргумент alias для метода Expression.get_group_by_cols() был удален.

Функции, устаревшие в Django 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(). Рекомендуется использовать модуль Python secrets для генерации паролей.
  • Шаблонный фильтр length_is больше не поддерживается.
  • Вместо этого используйте length и оператор == внутри тега {% if %}. Например, {% if value|length == 4 %}...{% endif %}.
  • Устарели хеш-функции 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. Рекомендуется использовать только аргументы, содержащие ключевые слова.

Взято с сайта: django.fun

;