Примечания к выпуску Django 5.0¶
4 декабря 2023 г.
Добро пожаловать в Джанго 5.0!
В этих примечаниях к выпуску описаны новые функции, а также некоторые обратно несовместимые изменения, о которых вам следует знать при обновлении с Django 4.2 или более ранней версии. Мы начали процесс прекращения поддержки некоторых функций.
См. руководство Обновление Django до новой версии, если вы обновляете существующий проект.
Совместимость версий Python¶
Django 5.0 поддерживает Python 3.10, 3.11 и 3.12. Мы настоятельно рекомендуем и официально поддерживаем только последнюю версию каждой серии.
Серия Django 4.2.x является последней версией, поддерживающей Python 3.8 и 3.9.
Поддержка сторонних библиотек для более старой версии Django¶
После выпуска Django 5.0 мы предлагаем сторонним авторам приложений прекратить поддержку всех версий Django до 4.2. В это время вы сможете запускать тесты вашего пакета с помощью python -Wd, чтобы появлялись предупреждения об устаревании. После исправления предупреждений об устаревании ваше приложение должно быть совместимо с Django 5.0.
Что нового в Джанго 5.0¶
Фасетные фильтры в админке¶
Количество фасетов теперь отображается для примененных фильтров в списке изменений администратора при включении через пользовательский интерфейс. Это поведение можно изменить с помощью нового атрибута ModelAdmin.show_facets. Для получения дополнительной информации см. Фасеты.
Упрощенные шаблоны для отрисовки полей формы.¶
В Django 5.0 представлена концепция группы полей и шаблонов групп полей. Это упрощает отрисовку связанных элементов поля формы Django, таких как его метка, виджет, текст справки и ошибки.
Например, шаблон ниже:
<form>
...
<div>
{{ form.name.label_tag }}
{% if form.name.help_text %}
<div class="helptext" id="{{ form.name.auto_id }}_helptext">
{{ form.name.help_text|safe }}
</div>
{% endif %}
{{ form.name.errors }}
{{ form.name }}
<div class="row">
<div class="col">
{{ form.email.label_tag }}
{% if form.email.help_text %}
<div class="helptext" id="{{ form.email.auto_id }}_helptext">
{{ form.email.help_text|safe }}
</div>
{% endif %}
{{ form.email.errors }}
{{ form.email }}
</div>
<div class="col">
{{ form.password.label_tag }}
{% if form.password.help_text %}
<div class="helptext" id="{{ form.password.auto_id }}_helptext">
{{ form.password.help_text|safe }}
</div>
{% endif %}
{{ form.password.errors }}
{{ form.password }}
</div>
</div>
</div>
...
</form>
Теперь можно упростить до:
<form>
...
<div>
{{ form.name.as_field_group }}
<div class="row">
<div class="col">{{ form.email.as_field_group }}</div>
<div class="col">{{ form.password.as_field_group }}</div>
</div>
</div>
...
</form>
as_field_group() отображает поля с помощью шаблона "django/forms/field.html" по умолчанию и может быть настроен для каждого проекта, для каждого поля или для каждого запроса. См. Многоразовые шаблоны групп полей.
Значения по умолчанию, вычисленные базой данных¶
Новый параметр Field.db_default устанавливает значение по умолчанию, вычисленное базой данных. Например:
from django.db import models
from django.db.models.functions import Now, Pi
class MyModel(models.Model):
age = models.IntegerField(db_default=18)
created = models.DateTimeField(db_default=Now())
circumference = models.FloatField(db_default=2 * Pi())
Поле модели, созданное базой данных¶
Новый GeneratedField позволяет создавать столбцы, генерируемые базой данных. Это поле можно использовать во всех поддерживаемых базах данных для создания поля, которое всегда вычисляется на основе других полей. Например:
from django.db import models
from django.db.models import F
class Square(models.Model):
side = models.IntegerField()
area = models.GeneratedField(
expression=F("side") * F("side"),
output_field=models.BigIntegerField(),
db_persist=True,
)
Дополнительные возможности для объявления выбора полей¶
Field.choices (для полей модели) и ChoiceField.choices (для полей формы) обеспечивают большую гибкость при объявлении их значений. В предыдущих версиях Django choices должен был быть либо списком из двух кортежей, либо подклассом Типы перечислений, но последний требовал доступа к атрибуту .choices для предоставления значений в ожидаемой форме:
from django.db import models
Medal = models.TextChoices("Medal", "GOLD SILVER BRONZE")
SPORT_CHOICES = [
("Martial Arts", [("judo", "Judo"), ("karate", "Karate")]),
("Racket", [("badminton", "Badminton"), ("tennis", "Tennis")]),
("unknown", "Unknown"),
]
class Winner(models.Model):
name = models.CharField(...)
medal = models.CharField(..., choices=Medal.choices)
sport = models.CharField(..., choices=SPORT_CHOICES)
В Django 5.0 добавлена поддержка принятия сопоставления или вызываемого объекта вместо итерируемого, а также больше не требуется непосредственное использование .choices для расширения типов перечисления:
from django.db import models
Medal = models.TextChoices("Medal", "GOLD SILVER BRONZE")
SPORT_CHOICES = { # Using a mapping instead of a list of 2-tuples.
"Martial Arts": {"judo": "Judo", "karate": "Karate"},
"Racket": {"badminton": "Badminton", "tennis": "Tennis"},
"unknown": "Unknown",
}
def get_scores():
return [(i, str(i)) for i in range(10)]
class Winner(models.Model):
name = models.CharField(...)
medal = models.CharField(..., choices=Medal) # Using `.choices` not required.
sport = models.CharField(..., choices=SPORT_CHOICES)
score = models.IntegerField(choices=get_scores) # A callable is allowed.
Под капотом предоставленные «выборы» нормализуются в список из двух кортежей в канонической форме всякий раз, когда значение «выбор» обновляется. Для получения дополнительной информации, пожалуйста, проверьте ссылку на поле модели по вариантам.
Минорные изменения¶
django.contrib.admin¶
Новый метод
AdminSite.get_log_entries()позволяет настраивать набор запросов для перечисленных записей журнала сайта.Административные фильтры
django.contrib.admin.AllValuesFieldListFilter,ChoicesFieldListFilter,RelatedFieldListFilterиRelatedOnlyFieldListFilterтеперь обрабатывают многозначные параметры запроса.XRegExpобновлен с версии 3.2.0 до 5.1.1.Новый метод
AdminSite.get_model_admin()возвращает класс администратора для данного класса модели.Свойства в
ModelAdmin.list_displayтеперь поддерживают логический атрибут.jQuery обновлен с версии 3.6.4 до 3.7.1.
django.contrib.auth¶
Число итераций по умолчанию для хэшера паролей PBKDF2 увеличено с 600 000 до 720 000.
Новые асинхронные функции теперь предоставляются с использованием префикса
a:django.contrib.auth.aauthenticate(),aget_user(),alogin(),alogout(), иaupdate_session_auth_hash().AuthenticationMiddlewareтеперь добавляет асинхронный методHttpRequest.auser(), который возвращает текущего пользователя, вошедшего в систему.Новая асинхронная функция
django.contrib.auth.hashers.acheck_password()и методAbstractBaseUser.acheck_password()позволяют асинхронно проверять пароли пользователей.
django.contrib.contenttypes¶
QuerySet.prefetch_lated()теперь поддерживает предварительную выборкуGenericForeignKeyс неоднородным набором результатов.
django.contrib.gis¶
Новая функция
ClosestPoint()возвращает двухмерную точку геометрии, ближайшую к другой геометрии.Агрегаты ГИС теперь поддерживают аргумент
filter.Добавлена поддержка GDAL 3.7 и GEOS 3.12.
Новый метод
GEOSGeometry.equals_identical()позволяет осуществлять поточечную проверку эквивалентности геометрии.
django.contrib.messages¶
Новый метод утверждения
MessagesTestMixin.assertMessages()позволяет тестироватьmessages, добавленный вответ.
django.contrib.postgres¶
Новый атрибут
violation_error_codeExclusionConstraintпозволяет настраиватькодValidationError, возникающий во время проверки модели.
Асинхронные представления¶
В ASGI теперь обрабатываются события
http.disconnect. Это позволяет представлениям выполнять любую необходимую очистку, если клиент отключается до того, как будет сгенерирован ответ. Дополнительную информацию см. в разделе Обработка отключений.
Декораторы¶
Следующие декораторы теперь поддерживают перенос функций асинхронного представления:
sensitivity_variables()sensitivity_post_parameters()условная_страница()xframe_options_deny()xframe_options_sameorigin()xframe_options_exempt()
Отчеты об ошибках¶
sensitive_variables()иsensitivity_post_parameters()теперь можно использовать с асинхронными функциями.
Хранение файлов¶
File.open()теперь передает все позиционные (*args) и ключевые аргументы (**kwargs) во встроенную функцию Pythonpython:open().
Формы¶
Новый аргумент
assume_schemeдляURLFieldпозволяет указать схему URL по умолчанию.Для улучшения доступности внесены следующие изменения:
Поля формы теперь включают HTML-атрибут
aria-describedby, позволяющий программам чтения с экрана связывать поля формы с их справочным текстом.Недопустимые поля формы теперь содержат HTML-атрибут
aria-invalid="true".
Интернационализация¶
Теперь доступна поддержка и переводы на уйгурский язык.
Миграции¶
Сериализация функций, оформленных с помощью
functools.cache()илиfunctools.lru_cache(), теперь поддерживается без необходимости писать собственный сериализатор.
Модели¶
Новый аргумент create_defaults методов
QuerySet.update_or_create()иQuerySet.aupdate_or_create()позволяет указывать различные значения полей для операции создания.Новый атрибут violation_error_code для
BaseConstraint,CheckConstraintиUniqueConstraintпозволяет настраиватькодValidationError``, возникающий во время проверки модели..Аргумент force_insert
Model.save()теперь позволяет указать кортеж родительских классов, которые необходимо принудительно вставить.Методы
QuerySet.bulk_create()иQuerySet.abulk_create()теперь устанавливают первичный ключ для каждого экземпляра модели, когда включен параметрupdate_conflicts(если база данных поддерживает его).Новый атрибут
UniqueConstraint.nulls_distinctпозволяет настраивать обработку значенийNULLв PostgreSQL 15+.Новые асинхронные ярлыки
aget_object_or_404()иaget_list_or_404()позволяют асинхронно получать объекты.Новая функция
aprefetch_related_objects()позволяет выполнять асинхронную предварительную выборку экземпляров модели.QuerySet.aiterator()теперь поддерживает предыдущие вызовыprefetch_related().В MariaDB 10.7+ UUIDField теперь создается как столбец UUID, а не столбец CHAR(32). Более подробную информацию о Миграция существующего UUIDField в MariaDB 10.7+ смотрите в руководстве по миграции выше.
Django теперь поддерживает oracledb версии 1.3.2 или выше. Поддержка cx_Oracle устарела с этого выпуска и будет удалена в Django 6.0.
Пагинация¶
Новый аргумент
django.core.paginator.Paginator.error_messagesпозволяет настраивать сообщения об ошибках, выдаваемыеPaginator.page().
Сигналы¶
Новые методы
Signal.asend()иSignal.asend_robust()позволяют асинхронную отправку сигналов. Приемники сигналов могут быть синхронными или асинхронными и автоматически адаптируются к правильному стилю вызова.
Шаблоны¶
Тесты¶
ClientиAsyncClientтеперь предоставляют асинхронные методы с использованием префиксаa:asession(),alogin(),aforce_login(), иalogout().AsyncClientтеперь поддерживает параметрfollow.DiscoverRunnerтеперь позволяет показывать продолжительность самых медленных тестов с помощью опцииtest --durations(доступно в Python 3.12+).
Валидаторы¶
Новый аргумент
offsetStepValueValidatorпозволяет указать смещение для допустимых значений.
Изменения обратной несовместимости в версии 5.0¶
Серверный API базы данных¶
В этом разделе описаны изменения, которые могут потребоваться в сторонних базах данных.
Для
DatabaseFeatures.supports_expression_defaultsдолжно быть установлено значениеFalse, если база данных не поддерживает использование функций базы данных по умолчанию.Для параметра
DatabaseFeatures.supports_default_keyword_in_insertдолжно быть установлено значениеFalse, если база данных не поддерживает ключевое словоDEFAULTв запросахINSERT.Для параметра DatabaseFeatures.supports_default_keyword_in_bulk_insert должно быть установлено значение False, если база данных не поддерживает ключевое слово DEFAULT в массовых запросах INSERT.
django.contrib.gis¶
Поддержка GDAL 2.2 и 2.3 удалена.
Поддержка GEOS 3.6 и 3.7 удалена.
django.contrib.sitemaps¶
Функция django.contrib.sitemaps.ping_google() и команда управления ping_google удалены, поскольку конечная точка ping Google Sitemaps устарела и будет удалена в январе 2024 года.
Класс исключений django.contrib.sitemaps.SitemapNotFound удален.
Прекращена поддержка MySQL <8.0.11.¶
Поддержка предварительных выпусков серии MySQL 8.0.x удалена. Django 5.0 поддерживает MySQL 8.0.11 и выше.
Использование create_defaults__exact теперь может потребоваться с QuerySet.update_or_create()¶
QuerySet.update_or_create() теперь поддерживает параметр create_defaults. Как следствие, любые модели, имеющие поле с именем create_defaults, которое используется с update_or_create(), должны указывать это поле в поиске с помощью create_defaults__exact.
Миграция существующего UUIDField в MariaDB 10.7+¶
В MariaDB 10.7+ UUIDField теперь создается как столбец UUID, а не столбец CHAR(32). Как следствие, любой UUIDField, созданный в Django < 5.0, должен быть заменен подклассом UUIDField, поддерживаемым CHAR(32):
class Char32UUIDField(models.UUIDField):
def db_type(self, connection):
return "char(32)"
def get_db_prep_value(self, value, connection, prepared=False):
value = super().get_db_prep_value(value, connection, prepared)
if value is not None:
value = value.hex
return value
Например:
class MyModel(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
Должно стать:
class Char32UUIDField(models.UUIDField): ...
class MyModel(models.Model):
uuid = Char32UUIDField(primary_key=True, default=uuid.uuid4)
Запуск команды makemigrations создаст миграцию, содержащую бездействующую операцию AlterField.
Разнообразный¶
Аргумент экземпляра недокументированного метода BaseModelFormSet.save_existing() переименован в obj.
Недокументированный django.contrib.admin.helpers.checkbox удален.
Целочисленные поля теперь проверяются как 64-битные целые числа в SQLite, чтобы соответствовать поведению sqlite3.
Недокументированный атрибут Query.annotation_select_mask изменен с набора строк на упорядоченный список строк.
ImageField.update_dimension_fields()больше не вызывается по сигналуpost_init, еслиwidth_fieldиheight_fieldне установлены.NowФункция базы данных теперь используетLOCALTIMESTAMPвместоCURRENT_TIMESTAMPв Oracle.AdminSite.site_headerтеперь отображается в теге<div>вместо<h1>. Пользователи программ чтения с экрана полагаются на элементы заголовков для навигации по странице. Наличие двух элементов<h1>сбивало с толку, а заголовок сайта был бесполезен, поскольку он повторяется на всех страницах.Чтобы улучшить доступность, основная область содержимого администратора и область содержимого заголовка теперь отображаются в тегах
<main>и<header>вместо<div>.В базах данных без встроенной поддержки оператора SQL
XORоператор^в качестве исключающего оператора или (XOR) теперь возвращает строки, которым соответствует нечетное количество операндов, а не ровно один операнд. Это соответствует поведению MySQL, MariaDB и Python.Минимальная поддерживаемая версия asgiref увеличена с 3.6.0 до 3.7.0.
Минимальная поддерживаемая версия Selenium увеличена с 3.8.0 до 4.8.0.
Исключения AlreadyRegistered и NotRegistered перенесены из django.contrib.admin.sites в django.contrib.admin.Exceptions.
Минимальная поддерживаемая версия SQLite увеличена с 3.21.0 до 3.27.0.
Поддержка
cx_Oracle< 8.3 удалена.Выполнение SQL-запросов до полного заполнения реестра приложений теперь вызывает
RuntimeWarning.BadRequestвызывается для запросов в кодировке, отличной от UTF-8, с типом контента application/x-www-form-urlencoded. Дополнительную информацию см. в RFC 1866.Минимальная поддерживаемая версия Colorama увеличена до 0.4.6.
Минимальная поддерживаемая версия docutils увеличена до 0.19.
Фильтрация наборов запросов по переполнению целочисленных значений теперь всегда возвращает пустой набор запросов. Как следствие, вам может потребоваться использовать
ExpressionWrapper()для явного переноса арифметики <using-f-with-annotations>` против целочисленных полей в таких случаях.
Функции, устаревшие в версии 5.0¶
Разнообразный¶
Средства визуализации переходных форм DjangoDivFormRenderer и Jinja2DivFormRenderer устарели.
Передача позиционных аргументов
nameиviolation_error_messageвBaseConstraintустарела в пользу аргументов, содержащих только ключевые слова.requestдобавляется в подписьModelAdmin.lookup_allowed(). Поддержка подклассов ModelAdmin, которые не принимают этот аргумент, устарела.Метод
get_joining_columns()дляForeignObjectиForeignObjectRelустарел. Начиная с Django 6.0,django.db.models.sql.datastructures.Joinбольше не будет использоватьget_joining_columns(). Вместо этого подклассы должны реализовать get_joining_fields().Метод «ForeignObject.get_reverse_joining_columns()» устарел.
Схема по умолчанию для form.URLField изменится с «http» на «https» в Django 6.0. Установите для переходного параметра
FORMS_URLFIELD_ASSUME_HTTPSзначениеTrue, чтобы принять использование"https"во время цикла выпуска Django 5.x.Переходная настройка
FORMS_URLFIELD_ASSUME_HTTPSустарела.Поддержка вызова
format_html()без передачи аргументов или kwargs будет удалена.Поддержка
cx_Oracleустарела в пользу драйвера Python`oracledb`_ 1.3.2+.DatabaseOperations.field_cast_sql()устарел в пользуDatabaseOperations.lookup_cast(). Начиная с Django 6.0,BuiltinLookup.process_lhs()больше не будет вызыватьfield_cast_sql(). Вместо этого сторонние базы данных должны реализовыватьlookup_cast().Метакласс django.db.models.enums.ChoicesMeta переименован в ChoicesType.
Метод Prefetch.get_current_queryset() устарел.
Метод get_prefetch_queryset() для связанных менеджеров и дескрипторов устарел. Начиная с Django 6.0,
get_prefetcher()иprefetch_related_objects()больше не будут возвращаться кget_prefetch_queryset(). Вместо этого подклассы должны реализовать get_prefetch_querysets().
Функции удалены в версии 5.0¶
Эти функции достигли конца цикла устаревания и удалены в Django 5.0.
См. Функции, устаревшие в версии 4.0 для получения подробной информации об этих изменениях, в том числе о том, как прекратить использование этих функций.
Параметр теста
SERIALIZEудален.Недокументированный модуль django.utils.baseconv удален.
Недокументированный модуль django.utils.datetime_safe удален.
Значение по умолчанию параметра USE_TZ изменено с False на True.
Протокол карты сайта по умолчанию для карт сайта, созданных вне контекста запроса, изменен с «http» на «https».
Аргумент
extra_testsдляDiscoverRunner.build_suite()иDiscoverRunner.run_tests()удален.Агрегаты
django.contrib.postgres.aggregates.ArrayAgg,JSONBAggиStringAggбольше не возвращают[],[]и''соответственно, если нет строк.Параметр
USE_L10Nудален.Переходный параметр
USE_DEPRECATED_PYTZудален.Поддержка часовых поясов pytz удалена.
Аргумент is_dst удален из:
QuerySet.datetimes()django.utils.timezone.make_aware()django.db.models.functions.Trunc()django.db.models.functions.TruncSecond()django.db.models.functions.TruncMinute()django.db.models.functions.TruncHour()django.db.models.functions.TruncDay()django.db.models.functions.TruncWeek()django.db.models.functions.TruncMonth()django.db.models.functions.TruncQuarter()django.db.models.functions.TruncYear()
Классы django.contrib.gis.admin.GeoModelAdmin и OSMGeoAdmin удалены.
Недокументированный метод BaseForm._html_output() удален.
Возможность возвращать
strвместоSafeStringпри рендерингеErrorDictиErrorListудалена.
См. Функции, устаревшие в версии 4.1 для получения подробной информации об этих изменениях, в том числе о том, как прекратить использование этих функций.
Метод SitemapIndexItem.__str__() удален.
Переходная настройка CSRF_COOKIE_MASKED удалена.
Аргумент
nameизdjango.utils.functional.cached_property()удален.Аргумент opclasses в django.contrib.postgres.constraints.ExclusionConstraint удален.
Недокументированная возможность передавать
errors=NoneвSimpleTestCase.assertFormError()иassertFormsetError()удалена.django.contrib.sessions.serializers.PickleSerializerудален.Использование QuerySet.iterator() в наборе запросов, который предварительно выбирает связанные объекты без предоставления аргумента chunk_size, больше не допускается.
Передача несохраненных экземпляров модели в связанные фильтры больше не разрешена.
created=Trueтребуется в сигнатуре подклассовRemoteUserBackend.configure_user().Поддержка выхода из системы с помощью запросов GET в django.contrib.auth.views.LogoutView и django.contrib.auth.views.logout_then_login() удалена.
Псевдоним django.utils.timezone.utc для datetime.timezone.utc удален.
Передача объекта ответа и имени формы/набора форм в
SimpleTestCase.assertFormError()иassertFormSetError()больше не разрешена.django.contrib.gis.admin.OpenLayersWidgetудален.
django.contrib.auth.hashers.CryptPasswordHasherудален.
Шаблоны
"django/forms/default.html"и"django/forms/formsets/default.html"удалены.Стиль рендеринга формы и набора форм по умолчанию изменен на основанный на div.
Передача nulls_first=False или nulls_last=False в методы Expression.asc() и Expression.desc(), а также выражение OrderBy больше не разрешены.