• 3.1
  • 3.2
  • 5.0
  • Версия документации: 6.1

Примечания к выпуску 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

django.contrib.contenttypes

  • QuerySet.prefetch_lated() теперь поддерживает предварительную выборку GenericForeignKey с неоднородным набором результатов.

django.contrib.gis

  • Новая функция ClosestPoint() возвращает двухмерную точку геометрии, ближайшую к другой геометрии.

  • Агрегаты ГИС теперь поддерживают аргумент filter.

  • Добавлена ​​поддержка GDAL 3.7 и GEOS 3.12.

  • Новый метод GEOSGeometry.equals_identical() позволяет осуществлять поточечную проверку эквивалентности геометрии.

django.contrib.messages

django.contrib.postgres

Асинхронные представления

  • В ASGI теперь обрабатываются события http.disconnect. Это позволяет представлениям выполнять любую необходимую очистку, если клиент отключается до того, как будет сгенерирован ответ. Дополнительную информацию см. в разделе Обработка отключений.

Декораторы

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

  • sensitive_variables() и sensitivity_post_parameters() теперь можно использовать с асинхронными функциями.

Хранение файлов

  • File.open() теперь передает все позиционные (*args) и ключевые аргументы (**kwargs) во встроенную функцию Python python: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.

Пагинация

Сигналы

  • Новые методы Signal.asend() и Signal.asend_robust() позволяют асинхронную отправку сигналов. Приемники сигналов могут быть синхронными или асинхронными и автоматически адаптируются к правильному стилю вызова.

Шаблоны

  • Новый шаблонный фильтр escapeseq применяет escape к каждому элементу последовательности.

Тесты

  • Client и AsyncClient теперь предоставляют асинхронные методы с использованием префикса a: asession(), alogin(), aforce_login(), и alogout().

  • AsyncClient теперь поддерживает параметр follow.

  • DiscoverRunner теперь позволяет показывать продолжительность самых медленных тестов с помощью опции test --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 в массовых запросах 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 больше не разрешены.

Back to Top