Примечания к выпуску Django 2.2¶
1 апреля 2019 г.
Добро пожаловать в Джанго 2.2!
Эти примечания к выпуску охватывают новые функции, а также некоторые обратно несовместимые изменения, о которых вам следует знать при обновлении с Django 2.1 или более ранней версии. Мы начали процесс прекращения поддержки некоторых функций.
См. руководство Обновление Django до новой версии, если вы обновляете существующий проект.
Django 2.2 обозначен как выпуск с долгосрочной поддержкой. Он будет получать обновления безопасности в течение как минимум трех лет после выпуска. Поддержка предыдущей LTS, Django 1.11, закончится в апреле 2020 года.
Совместимость версий Python¶
Django 2.2 поддерживает Python 3.5, 3.6, 3.7, 3.8 (начиная с 2.2.8) и 3.9 (начиная с 2.2.17). Мы настоятельно рекомендуем и официально поддерживаем только последнюю версию каждой серии.
Что нового в Джанго 2.2¶
Ограничения¶
Новые классы CheckConstraint и UniqueConstraint позволяют добавлять пользовательские ограничения базы данных. Ограничения добавляются в модели с помощью опции Meta.constraints.
Минорные изменения¶
django.contrib.admin¶
Добавлен класс CSS в заголовки столбцов
TabularInline.
django.contrib.auth¶
HttpRequest теперь передается в качестве первого позиционного аргумента в
RemoteUserBackend.configure_user(), если он его принимает.
django.contrib.gis¶
django.contrib.postgres¶
Новый аргумент упорядочения для
ArrayAggиStringAggопределяет порядок агрегированных элементов.Новые классы
BTreeIndex,HashIndexиSpGistIndexпозволяют создаватьB-Tree,hashиSP-GiSTиндексы в базе данных.BrinIndexтеперь имеет параметрautosummarize.Новый параметр
search_typeSearchQueryпозволяет искать фразу или необработанное выражение.
django.contrib.staticfiles¶
Добавлено сопоставление пути к опции
collectstatic --ignore, чтобы можно было использовать такие шаблоны, как/vendor/*.js.
Серверные базы данных¶
Добавлена потоковая передача результатов для
QuerySet.iterator()в SQLite.
Общие представления¶
Новый хук
View.setupинициализирует атрибуты представления перед вызовомdispatch(). Это позволяет миксинам настраивать атрибуты экземпляра для повторного использования в дочерних классах.
Интернационализация¶
Добавлена поддержка и переводы на армянский язык.
Команды управления¶
Новая опция
--force-colorпринудительно раскрашивает вывод команды.inspectdbтеперь создает модели для сторонних таблиц в PostgreSQL.inspectdb --include-viewsтеперь создает модели для материализованных представлений в Oracle и PostgreSQL.Новая опция
inspectdb --include-partitionsпозволяет создавать модели для таблиц разделов в PostgreSQL. В более старых версиях моделей создаются дочерние таблицы вместо родительских.inspectdbтеперь анализируетDurationFieldдля Oracle и PostgreSQL иAutoFieldдля SQLite.В Oracle
dbshellобернутrlwrap, если он доступен.rlwrapобеспечивает историю команд и редактирование ввода с клавиатуры.Новая опция
makemigrations --no-headerпозволяет избежать записи комментариев заголовка в сгенерированных файлах миграции. Эта опция также доступна дляsquashmigrations.runserverтеперь может использовать Watchman для повышения производительности при отслеживании изменений в большом количестве файлов.
Миграции¶
Новая опция
migrate --planвыводит список операций миграции, которые будут выполнены.NoneTypeтеперь можно сериализовать при миграции.Теперь вы можете зарегистрировать пользовательские сериализаторы для миграций.
Модели¶
Добавлена поддержка классов операторов PostgreSQL (
Index.opclasses).Добавлена поддержка частичных индексов (
Index.condition).Добавлены функции базы данных
NullIfиReverse, а также множество математических функций базы данных.Установка для нового параметра
ignore_conflictsQuerySet.bulk_create()значенияTrueсообщает базе данных игнорировать ошибки при вставке строк, которые не соответствуют ограничениям уникальности или другим проверкам.Новая функция
ExtractIsoYearизвлекает годы с нумерацией недель ISO-8601 изDateFieldиDateTimeField, а новый поискiso_yearпозволяет делать запросы по ISO-8601 — нумерация недель года.Новый метод
QuerySet.bulk_update()позволяет эффективно обновлять определенные поля в нескольких экземплярах модели.Django больше не всегда запускает транзакцию при выполнении одного запроса, например Model.save(), QuerySet.update() и Model.delete(). Это повышает производительность автофиксации за счет уменьшения количества обращений к базе данных.
Обработка агрегации DISTINCT добавлена в класс
Aggregate. Добавлениеallow_distinct = Trueв качестве атрибута класса в подклассахAggregateпозволяет указать аргумент ключевого словаdistinctпри инициализации, чтобы гарантировать, что агрегатная функция вызывается только для каждого отдельного значениявыражений.Методы
RelatedManager.add(),create(),remove(),set(),get_or_create()иupdate_or_create()теперь разрешены для отношений «многие ко многим» с промежуточными моделями. Новый аргумент «through_defaults» используется для указания значений для новых экземпляров промежуточной модели.
Запросы и ответы¶
Добавлен
HttpRequest.headers, чтобы обеспечить простой доступ к заголовкам запроса.
Сериализация¶
Теперь вы можете десериализовать данные, используя естественные ключи, содержащие прямые ссылки, передав
handle_forward_references=Trueвserializers.deserialize(). Кроме того,loaddataавтоматически обрабатывает прямые ссылки.
Тесты¶
Новое утверждение
SimpleTestCase.assertURLEqual()проверяет заданный URL-адрес, игнорируя порядок строки запроса.assertRedirects()использует новое утверждение.Тест
Clientтеперь поддерживает автоматическую сериализацию JSON списка и кортежаданных, когдаcontent_type='application/json'.Новая настройка тестовой базы данных
ORACLE_MANAGED_FILESпозволяет использовать табличные пространства Oracle Managed Files (OMF).Отложенные ограничения базы данных теперь проверяются в конце каждого теста
TestCaseв SQLite 3.20+, как и в других бэкэндах, поддерживающих отложенные ограничения. Эти проверки не реализованы для более старых версий SQLite, поскольку там они потребовали бы дорогостоящего самоанализа таблиц.DiscoverRunnerтеперь пропускает настройку баз данных, на которые не ссылаются тесты.
URL-адреса¶
Новый атрибут
ResolverMatch.routeхранит маршрут соответствующего шаблона URL.
Валидаторы¶
MaxValueValidator,MinValueValidator,MinLengthValidatorиMaxLengthValidatorтеперь принимают вызываемоеlimit_value.
Изменения обратной несовместимости в версии 2.2¶
Серверный API базы данных¶
В этом разделе описаны изменения, которые могут потребоваться в сторонних базах данных.
Сторонние базы данных должны реализовать поддержку ограничений проверки таблиц или установить для параметра DatabaseFeatures.supports_table_check_constraints значение False.
Сторонние базы данных должны реализовывать поддержку игнорирования ограничений или ошибок уникальности при вставке или установке для
DatabaseFeatures.supports_ignore_conflictsзначенияFalse.Сторонние базы данных должны реализовать интроспекцию для DurationField или установить для DatabaseFeatures.can_introspect_duration_field значение False.
DatabaseFeatures.uses_savepointsтеперь по умолчанию имеет значениеTrue.Сторонние базы данных должны реализовать поддержку частичных индексов или установить для
DatabaseFeatures.supports_partial_indexesзначениеFalse.DatabaseIntrospection.table_name_converter()иcolumn_name_converter()удалены. Сторонним базам данных может потребоваться вместо этого реализоватьDatabaseIntrospection.identifier_converter(). В этом случае имена ограничений, которые возвращает DatabaseIntrospection.get_constraints(), должны быть нормализованы с помощью identifier_converter().Генерация SQL для индексов перенесена из
IndexвSchemaEditor, и добавлены следующиеSchemaEditorметоды:_create_primary_key_sql()и_delete_primary_key_sql()_delete_index_sql()(для сопряжения с_create_index_sql())_delete_unique_sql(для сопряжения с_create_unique_sql())_delete_fk_sql()(для пары с_create_fk_sql())_create_check_sql()и_delete_check_sql()
Третий аргумент
DatabaseWrapper.__init__(),allow_thread_sharing, удален.
Действия администратора больше не собираются из базовых классов ModelAdmin.¶
Например, в старых версиях Django:
from django.contrib import admin
class BaseAdmin(admin.ModelAdmin):
actions = ["a"]
class SubAdmin(BaseAdmin):
actions = ["b"]
SubAdmin будет иметь действия 'a' и 'b'.
Теперь действия следуют стандартному наследованию Python. Чтобы получить тот же результат, что и раньше:
class SubAdmin(BaseAdmin):
actions = BaseAdmin.actions + ["b"]
django.contrib.gis¶
Поддержка GDAL 1.9 и 1.10 прекращена.
TransactionTestCase сериализованная загрузка данных¶
Первоначальные миграции данных теперь загружаются в TransactionTestCase в конце теста, после очистки базы данных. В более старых версиях эти данные загружались в начале теста, но это мешает опции test --keepdb работать корректно (база данных была пуста в конце всего набора тестов). Это изменение не должно повлиять на ваши тесты, если вы не настроили внутренние компоненты TransactionTestCase.
sqlparse является обязательной зависимостью¶
Чтобы упростить некоторые части обработки базы данных Django, sqlparse 0.2.2+ теперь является обязательной зависимостью. Он автоматически устанавливается вместе с Django.
псевдонимы cached_property¶
В использовании как:
from django.utils.functional import cached_property
class A:
@cached_property
def base(self):
return ...
alias = base
псевдоним не кэшируется. Там, где проблема может быть обнаружена (Python 3.6 и более поздние версии), такое использование теперь вызывает ошибку «TypeError: невозможно назначить одно и то же кэшированное_свойство двум разным именам («базовый» и «псевдоним»).
Используйте это вместо этого:
import operator
class A:
...
alias = property(operator.attrgetter("base"))
Разрешения для прокси-моделей¶
Разрешения для прокси-моделей теперь создаются с использованием типа контента прокси-модели, а не типа контента конкретной модели. Миграция обновит существующие разрешения при запуске migrate.
В администраторе изменение прозрачно для прокси-моделей, имеющих ту же метку app_label, что и их конкретная модель. Однако в более старых версиях пользователи с разрешениями на прокси-модель с отличной app_label от конкретной модели не могли получить доступ к модели в администраторе. Сейчас это исправлено, но вы можете проверить назначения разрешений для таких моделей прокси ([add|view|change|delete]_myproxy) перед обновлением, чтобы убедиться, что новый доступ подходит.
Наконец, строки разрешений модели прокси должны быть обновлены, чтобы использовать собственную app_label. Например, для app.MyProxyModel, наследуемого от other_app.ConcreteModel, обновите user.has_perm('other_app.add_myproxymodel') до user.has_perm('app.add_myproxymodel').
Объединение активов формы «Медиа»¶
Ресурсы формы «Медиа» теперь объединяются с использованием алгоритма топологической сортировки, поскольку старый алгоритм попарного слияния в некоторых случаях недостаточен. Файлы CSS и JavaScript, не содержащие своих зависимостей, теперь могут сортироваться неправильно (в то время как старый алгоритм по совпадению выдавал правильные результаты).
Проверьте все классы Media на наличие отсутствующих зависимостей. Например, виджеты, зависящие от django.jQuery, должны указывать js=['admin/js/jquery.init.js', ...] при объявлении медиа-ресурсов формы <assets-as-a-static-definition>`.
Разнообразный¶
Чтобы улучшить читаемость, поле формы UUIDField теперь отображает значения через тире, например:
550e8400-e29b-41d4-a716-446655440000вместо550e8400e29b41d4a716446655440000.В SQLite PositiveIntegerField и PositiveSmallIntegerField теперь включают проверочное ограничение для предотвращения отрицательных значений в базе данных. Если у вас есть недопустимые данные и вы запустили миграцию, которая воссоздает таблицу, вы увидите сообщение «Ошибка ограничения CHECK».
Для обеспечения совместимости с серверами WSGI тестовый клиент теперь устанавливает заголовок Content-Length в виде строки, а не целого числа.
Возвращаемое значение
django.utils.text.slugify()больше не помечается как безопасное для HTML.Символом усечения по умолчанию, используемым фильтрами шаблонов
urlizetrunc,truncatechars,truncatechars_html,truncatewordsиtruncatewords_html, теперь является настоящий символ многоточия (…) вместо 3 точек. Возможно, вам придется адаптировать некоторые сравнения результатов тестов.Поддержка путей байтовых строк в загрузчике файловой системы шаблона удалена.
django.utils.http.urlsafe_base64_encode()теперь возвращает строку вместо байтовой строки, аdjango.utils.http.urlsafe_base64_decode()больше не может передавать байтовую строку.Поддержка
cx_Oracle< 6.0 удалена.Минимальная поддерживаемая версия mysqlclient увеличена с 1.3.7 до 1.3.13.
Минимальная поддерживаемая версия SQLite увеличена с 3.7.15 до 3.8.3.
В попытке предоставить больше семантических данных запроса NullBooleanSelect теперь отображает значения
<option>значенияunknown,trueиfalseвместо1,2и3. В целях обратной совместимости старые значения по-прежнему принимаются как данные.Group.namemax_lengthувеличено с 80 до 150 символов.Тесты, нарушающие ограничения базы данных с возможностью отсрочки, теперь выдают ошибку при запуске на SQLite 3.20+, как и на других бэкэндах, поддерживающих такие ограничения.
Чтобы выявить ошибки использования, тесты
Clientиdjango.utils.http.urlencode()теперь вызываютTypeError, еслиNoneпередается как значение для кодирования, посколькуNoneне может быть закодировано в данных GET и POST. Либо передайте пустую строку, либо опустите значение.Команда управления
ping_googleтеперь по умолчанию используетhttpsвместоhttpдля URL-адреса карты сайта. Если ваш сайт использует http, используйте новую опциюping_google --sitemap-use-http. Если вы используете функцию django.contrib.sitemaps.ping_google, установите для нового аргумента sitemap_uses_https значение False.runserverбольше не поддерживаетpyinotify(заменён на Watchman).Агрегатные функции
Avg,StdDevиVarianceтеперь возвращаютDecimalвместоfloat, если входные данные имеютDecimal.Тесты на SQLite не пройдут, если приложения без миграции связаны с приложениями с миграцией. Это было задокументировано с тех пор, как в Django 1.7 были добавлены миграции, но теперь оно работает более надежно. Вы увидите, что тесты завершаются неудачно с ошибками типа
нет такой таблицы: <app_label>_<model>. Это наблюдалось в нескольких сторонних приложениях, модели которых находились в тестах без миграции. Для таких моделей необходимо добавить миграции.Предоставление целого числа в аргументе
keycache.delete()илиcache.get()теперь вызываетValueError.Множественные уравнения для некоторых языков изменены, поскольку включены последние версии Transifex.
Примечание
Возможность обработки файлов .po, содержащих различные уравнения множественного числа для одного и того же языка, была добавлена в Django 2.2.12.
Функции, устаревшие в версии 2.2¶
Модель Meta.ordering больше не влияет на запросы GROUP BY.¶
Meta.ordering модели, влияющий на запросы GROUP BY (например, .annotate().values()), является распространенным источником путаницы. Такие запросы теперь выдают предупреждение об устаревании с советом добавить order_by() для сохранения текущего запроса. Meta.ordering будет игнорироваться в таких запросах, начиная с Django 3.1.
Разнообразный¶
django.utils.timezone.FixedOffsetустарел в пользуdatetime.timezone.Недокументированный псевдоним
QuerySetPaginatorдляdjango.core.paginator.Paginatorустарел.Модель FloatRangeField и поля формы в django.contrib.postgres устарели в пользу нового имени DecimalRangeField, чтобы соответствовать базовому типу данных numrange, используемому в базе данных.
Параметр
FILE_CHARSETустарел. Начиная с Django 3.1, файлы, считываемые с диска, должны иметь кодировку UTF-8.django.contrib.staticfiles.storage.CachedStaticFilesStorageустарел из-за имеющихся у него неразрешимых проблем. Вместо этого используйтеManifestStaticFilesStorageили стороннее облачное хранилище.RemoteUserBackend.configure_user()теперь передаетсяrequestв качестве первого позиционного аргумента, если он его принимает. Поддержка переопределений, которые ее не принимают, будет удалена в Django 3.1.Атрибуты SimpleTestCase.allow_database_queries, TransactionTestCase.multi_db и TestCase.multi_db устарели в пользу
SimpleTestCase.databases,TransactionTestCase.databasesиTestCase.databases. Эти новые атрибуты позволяют объявлять зависимости баз данных, чтобы предотвратить утечку состояния между неожиданными запросами к базам данных не по умолчанию. Предыдущее поведениеallow_database_queries=Trueиmulti_db=Trueможет быть достигнуто путем установкиdatabases='__all__'.