Cat

Список изменений Django 5.0 на русском языке

Эти заметки к релизу охватывают новые функции, а также некоторые изменения, несовместимые с предыдущими версиями, о которых вам следует знать при обновлении с Django 4.2 или более ранних версий. Мы начали процесс устаревания некоторых функций.

Django proDream 05 Декабрь 2023 Просмотров: 1682

Эти заметки к релизу охватывают новые функции, а также некоторые изменения, несовместимые с предыдущими версиями, о которых вам следует знать при обновлении с 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-элементных кортежей в качестве канонической формы всякий раз, когда значение выбора обновляется. Дополнительную информацию можно найти в справочнике по полям модели для выбора.

 

Незначительные нововведения

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 теперь поддерживают логический (boolean) атрибут.
  • jQuery обновлен с версии 3.6.4 до 3.7.1.

 

django.contrib.auth:

 

django.contrib.contenttypes:

 

django.contrib.gis:

  • Новая функция 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. Это позволяет представлениям выполнять необходимую очистку, если клиент отключается до генерации ответа. См. Обработка отключений для получения более подробной информации.

 

Декораторы:
Следующие декораторы теперь поддерживают оборачивание асинхронных функций представлений:

 

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

 

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

  • Метод File.open() теперь передает все позиционные (*args) и ключевые аргументы (**kwargs) встроенной функции open() в Python.

 

Формы:

  • Новый аргумент 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 применяет экранирование к каждому элементу последовательности.

 

Тесты:

  • Теперь 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.

Автор

    Нет комментариев

    Реклама