Новые функции и изменения в Django 4.2: примечания к выпуску
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