Список изменений Django 5.0 на русском языке
Эти заметки к релизу охватывают новые функции, а также некоторые изменения, несовместимые с предыдущими версиями, о которых вам следует знать при обновлении с Django 4.2 или более ранних версий. Мы начали процесс устаревания некоторых функций.
Реклама
Эти заметки к релизу охватывают новые функции, а также некоторые изменения, несовместимые с предыдущими версиями, о которых вам следует знать при обновлении с 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
. - Добавлена поддержка
GDAL
3.7 иGEOS
3.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
.
Все статьи