Эти заметки к релизу охватывают новые функции, а также некоторые изменения, несовместимые с предыдущими версиями, о которых вам следует знать при обновлении с Django 4.2 или более ранних версий. Мы начали процесс устаревания некоторых функций.
Посмотрите руководство "Как обновить Django до новой версии", если вы обновляете существующий проект.
Новость к релизу можно прочесть по ссылке: Релиз Django 5.0
Оригинальный список изменений на английском языке доступен по ссылке: https://docs.djangoproject.com/en/5.0/releases/5.0/
Совместимость с 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.
Что нового в Django 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, выбор должен был быть либо списком из 2-элементных кортежей, либо подклассом типа Enum, но последний требовал доступа к атрибуту .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 = { # Использование словаря вместо списка из 2-элементных кортежей.
"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) # Использование .choices не обязательно.
sport = models.CharField(..., choices=SPORT_CHOICES)
score = models.IntegerField(choices=get_scores) # Разрешено использование вызываемого объекта.
Под капотом предоставленные варианты выбора нормализуются в список из 2-элементных кортежей в качестве канонической формы всякий раз, когда значение выбора обновляется. Дополнительную информацию можно найти в справочнике по полям модели для выбора.
Незначительные нововведения
- Новый метод 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 теперь поддерживают логический (boolean) атрибут.
jQueryобновлен с версии 3.6.4 до 3.7.1.
- Стандартное количество итераций для хеширования пароля 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() позволяют асинхронно проверять пароли пользователей.
- Теперь метод QuerySet.prefetch_related() поддерживает предварительную выборку GenericForeignKey с неоднородным набором результатов.
- Новая функция ClosestPoint() возвращает двумерную точку на геометрии, которая находится ближе всего к другой геометрии.
- Теперь агрегаты GIS поддерживают аргумент
filter. - Добавлена поддержка
GDAL3.7 иGEOS3.12. - Новый метод GEOSGeometry.equals_identical() позволяет проводить проверку эквивалентности геометрий точка-за-точку.
django.contrib.messages:
Новый метод проверки assertMessages() в MessagesTestMixin позволяет тестировать сообщения, добавленные к ответу.
django.contrib.postgres:
Новый атрибут violation_error_code у ExclusionConstraint позволяет настраивать код ValidationError, вызываемый во время валидации модели.
Асинхронные представления:
- Под ASGI теперь обрабатываются события
http.disconnect. Это позволяет представлениям выполнять необходимую очистку, если клиент отключается до генерации ответа. См. Обработка отключений для получения более подробной информации.
Декораторы:
Следующие декораторы теперь поддерживают оборачивание асинхронных функций представлений:
cache_control()never_cache()no_append_slash()csrf_exempt()csrf_protect()ensure_csrf_cookie()requires_csrf_token()sensitive_variables()sensitive_post_parameters()gzip_page()condition()conditional_page()etag()last_modified()require_http_methods()require_GET()require_POST()require_safe()vary_on_cookie()vary_on_headers()xframe_options_deny()xframe_options_sameorigin()xframe_options_exempt()
Отчет об ошибках:
- Теперь функции sensitive_variables() и sensitive_post_parameters() могут быть использованы с асинхронными функциями.
Хранение файлов:
- Метод File.open() теперь передает все позиционные
(*args)и ключевые аргументы(**kwargs)встроенной функции open() в Python.
Формы:
- Новый аргумент assume_scheme для URLField позволяет указать схему URL по умолчанию.
- Для улучшения доступности внесены следующие изменения:
- Поля форм теперь включают атрибут HTML
aria-describedby, чтобы позволить программам чтения экрана ассоциировать поля формы с текстом помощи к ним. - Неверные поля формы теперь включают атрибут HTML
aria-invalid="true".
- Поля форм теперь включают атрибут HTML
Интернационализация:
- Теперь доступна поддержка и переводы для уйгурского языка.
Миграции:
- Теперь поддерживается сериализация функций, декорированных с использованием 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.
Пагинация:
- Новый аргумент error_messages в django.core.paginator.Paginator позволяет настраивать сообщения об ошибках, вызываемые методом Paginator.page().
Сигналы:
- Новые методы Signal.asend() и Signal.asend_robust() позволяют асинхронную отправку сигналов. Приемники сигналов могут быть синхронными или асинхронными и автоматически адаптируются к правильному стилю вызова.
Шаблоны:
Новый фильтр шаблона escapeseq применяет экранирование к каждому элементу последовательности.
Тесты:
- Теперь Client и AsyncClient предоставляют асинхронные методы с префиксом
"a":asession(),alogin(),aforce_login()иalogout(). AsyncClientтеперь поддерживает параметрfollow.- Новая опция теста
--durationsпозволяет отображать продолжительность самых медленных тестов на Python 3.12+.
Валидаторы:
- Новый аргумент
offsetуStepValueValidatorпозволяет указывать смещение для допустимых значений.
Изменения обратной несовместимости в версии 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в запросах массовой вставки (bulk 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)"
Например:
class MyModel(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
Должно стать:
class Char32UUIDField(models.UUIDField):
def db_type(self, connection):
return "char(32)"
class MyModel(models.Model):
uuid = Char32UUIDField(primary_key=True, default=uuid.uuid4)При выполнении команды makemigrations будет создана миграция, содержащая операцию AlterField без изменений.
Разное
- Аргумент
instanceв неописанном методеsave_existing()классаBaseModelFormSetтеперь переименован вobj. - Удален неописанный элемент
django.contrib.admin.helpers.checkbox. - Целочисленные поля теперь валидируются как 64-битные целые числа в SQLite для согласования с поведением
sqlite3. - Атрибут
annotation_select_maskв классеQuery, который ранее не был описан, изменен с набора строк на упорядоченный список строк. - Метод
update_dimension_fields()классаImageFieldбольше не вызывается на сигналеpost_init, еслиwidth_fieldиheight_fieldне установлены. - Функция Now базы данных использует
LOCALTIMESTAMPвместоCURRENT_TIMESTAMPна Oracle. - AdminSite.site_header теперь отображается в теге
<div>вместо<h1>. Пользователи считывающих устройств полагаются на элементы заголовка для навигации по странице. Имея два элемента<h1>было запутывающим, и заголовок сайта не был полезным, так как он повторяется на всех страницах. - Для улучшения доступности основная область контента администратора и область содержимого заголовка теперь отображаются в тегах
<main>и<header>вместо<div>. - На базах данных без встроенной поддержки оператора
XORв SQL, оператор^как оператор исключающегоИЛИ(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.
- Для запросов, не кодированных в UTF-8 и имеющих тип содержимого
application/x-www-form-urlencoded, теперь вызывается BadRequest. См. RFC 1866 для получения дополнительной информации. - Минимальная поддерживаемая версия
coloramaувеличена до 0.4.6. - Минимальная поддерживаемая версия
docutilsувеличена до 0.19.
Функции, устаревшие в версии 5.0
Разное
- Переходные рендереры форм
DjangoDivFormRendererиJinja2DivFormRendererобъявлены устаревшими. - Передача позиционных аргументов
nameиviolation_error_messageв BaseConstraint устаревает в пользу только ключевых аргументов. - В сигнатуру ModelAdmin.lookup_allowed() добавлен аргумент
request. Поддержка подклассовModelAdmin, которые не принимают этот аргумент, устаревает. - Метод
get_joining_columns()ForeignObjectиForeignObjectRelобъявлен устаревшим. Начиная с Django 6.0,Joinизdjango.db.models.sql.datastructuresбольше не будет использоватьget_joining_columns(). Вместо этого подклассы должны реализовать методget_joining_fields(). - Метод
ForeignObject.get_reverse_joining_columns()объявлен устаревшим. - Схема по умолчанию для
forms.URLFieldизменится с "http" на "https" в Django 6.0. Установите параметр FORMS_URLFIELD_ASSUME_HTTPS вTrueдля переходного периода Django 5.x, чтобы предполагать "https". - Переходный параметр
FORMS_URLFIELD_ASSUME_HTTPSобъявлен устаревшим. - Поддержка вызова
format_html()без передачи аргументов или ключевых аргументов будет удалена. - Поддержка
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(). - Метакласс
ChoicesMetaизdjango.db.models.enumsпереименован в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удалён из: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.
Комментарии
Оставить комментарийВойдите, чтобы оставить комментарий.
Комментариев пока нет.