Примечания к выпуску Django 2.2¶
1 апреля 2019 года
Добро пожаловать в Django 2.2!
Эти заметки о выпуске охватывают new features, а также некоторые backwards incompatible changes, о которых вы должны знать при переходе с Django 2.1 или более ранней версии. Мы begun the deprecation process for some features.
См. руководство Как обновить Django до более новой версии, если вы обновляете существующий проект.
Django 2.2 обозначен как long-term support release. Она будет получать обновления безопасности в течение как минимум трех лет после выпуска. Поддержка предыдущей 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). Мы настоятельно рекомендуем и официально поддерживаем только последний выпуск каждой серии.
Что нового в Django 2.2¶
Ограничения¶
Новые классы CheckConstraint
и UniqueConstraint
позволяют добавлять пользовательские ограничения базы данных. Ограничения добавляются в модели с помощью опции Meta.constraints
.
Незначительные особенности¶
django.contrib.admin
¶
- Добавлен CSS-класс для заголовков столбцов
TabularInline
.
django.contrib.auth
¶
- Теперь
HttpRequest
передается как первый позиционный аргумент вRemoteUserBackend.configure_user()
, если он его принимает.
django.contrib.postgres
¶
- Новый аргумент
ordering
дляArrayAgg
иStringAgg
определяет порядок следования агрегированных элементов. - Новые классы
BTreeIndex
,HashIndex
иSpGistIndex
позволяют создавать индексыB-Tree
,hash
иSP-GiST
в базе данных. BrinIndex
теперь имеет параметрautosummarize
.- Новый параметр
search_type
вSearchQuery
позволяет искать по фразе или необработанному выражению.
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
теперь можно сериализовать в миграциях.- Теперь вы можете register custom serializers для миграций.
Модели¶
- Добавлена поддержка классов операторов PostgreSQL (
Index.opclasses
). - Добавлена поддержка частичных индексов (
Index.condition
). - Добавлены функции базы данных
NullIf
иReverse
, а также множество math database functions. - Установка нового параметра
ignore_conflicts
изQuerySet.bulk_create()
вTrue
указывает базе данных игнорировать отказ вставки строк, которые не проходят ограничения уникальности или другие проверки. - Новая функция
ExtractIsoYear
извлекает годы недели по ISO-8601 изDateField
иDateTimeField
, а новый поискiso_year
позволяет выполнять запрос по году недели по ISO-8601. - Новый метод
QuerySet.bulk_update()
позволяет эффективно обновлять определенные поля на нескольких экземплярах модели. - Django больше не всегда начинает транзакцию при выполнении одного запроса, например,
Model.save()
,QuerySet.update()
иModel.delete()
. Это улучшает производительность autocommit, уменьшая количество обходов базы данных. - Добавлена поддержка SQLite для функций
StdDev
иVariance
. - Обработка агрегации
DISTINCT
добавлена в классAggregate
. Добавлениеallow_distinct = True
в качестве атрибута класса для подклассовAggregate
позволяет указать аргумент ключевого словаdistinct
при инициализации, чтобы гарантировать, что агрегатная функция вызывается только для каждого отдельного значенияexpressions
. - Методы
RelatedManager.add()
,create()
,remove()
,set()
,get_or_create()
иupdate_or_create()
теперь разрешены для отношений «многие-ко-многим» с промежуточными моделями. Новый аргументthrough_defaults
используется для указания значений для новых экземпляров промежуточных моделей.
Запросы и ответы¶
- Добавлено
HttpRequest.headers
для простого доступа к заголовкам запроса.
Сериализация¶
- Теперь вы можете десериализовать данные, используя натуральные ключи, содержащие forward references, передавая
handle_forward_references=True
вserializers.deserialize()
. Кроме того,loaddata
автоматически обрабатывает прямые ссылки.
Тесты¶
- Новое утверждение
SimpleTestCase.assertURLEqual()
проверяет заданный URL, игнорируя порядок строки запроса.assertRedirects()
использует новое утверждение. - Тест
Client
теперь поддерживает автоматическую JSON сериализацию списка и кортежаdata
приcontent_type='application/json'
. - Новая настройка тестовой базы данных
ORACLE_MANAGED_FILES
позволяет использовать табличные пространства Oracle Managed Files (OMF). - Откладываемые ограничения базы данных теперь проверяются в конце каждого теста
TestCase
на SQLite 3.20+, как и на других бэкендах, поддерживающих откладываемые ограничения. Эти проверки не реализованы для более старых версий SQLite, поскольку они потребовали бы дорогостоящего интроспекта таблиц. DiscoverRunner
теперь пропускает настройку баз данных не referenced by tests.
URLs¶
- Новый атрибут
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'
.
Теперь actions
следует стандартному наследованию 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
alias
не кэшируется. Там, где проблема может быть обнаружена (Python 3.6 и более поздние версии), такое использование теперь вызывает ошибку TypeError: Cannot assign the same cached_property to two different names ('base' and 'alias').
Вместо этого используйте следующее:
import operator
class A:
...
alias = property(operator.attrgetter('base'))
Разрешения для прокси-моделей¶
Permissions for proxy models теперь создаются с использованием типа содержимого прокси-модели, а не типа содержимого конкретной модели. При миграции существующие разрешения будут обновлены при запуске 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')
.
Слияние активов формы Media
¶
Активы формы Media
теперь объединяются с помощью алгоритма топологической сортировки, так как старый алгоритм попарного объединения недостаточен для некоторых случаев. Файлы CSS и JavaScript, не включающие свои зависимости, теперь могут быть отсортированы неправильно (там, где старый алгоритм по совпадению выдавал правильные результаты).
Проверьте все классы Media
на наличие отсутствующих зависимостей. Например, виджеты, зависящие от django.jQuery
, должны указывать js=['admin/js/jquery.init.js', ...]
при declaring form media assets.
Разное¶
Для улучшения читабельности поле формы
UUIDField
теперь отображает значения с тире, например,550e8400-e29b-41d4-a716-446655440000
вместо550e8400e29b41d4a716446655440000
.На SQLite,
PositiveIntegerField
иPositiveSmallIntegerField
теперь включают проверочное ограничение для предотвращения отрицательных значений в базе данных. Если у вас есть недопустимые данные и вы запустили миграцию, которая воссоздает таблицу, вы увидитеCHECK constraint failed
.Для согласованности с серверами WSGI тестовый клиент теперь устанавливает заголовок
Content-Length
в строку, а не в целое число.Возвращаемое значение
django.utils.text.slugify()
больше не помечается как HTML-безопасное.Символ усечения, используемый по умолчанию фильтрами шаблонов
urlizetrunc
,truncatechars
,truncatechars_html
,truncatewords
иtruncatewords_html
, теперь представляет собой настоящий символ многоточия (…
) вместо трех точек. Возможно, вам придется адаптировать некоторые тестовые сравнения вывода.Устранена поддержка байтовых путей в загрузчике файловой системы шаблона.
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.name
max_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-uses-http
. Если вы используете функциюping_google()
, установите новый аргументsitemap_uses_https
в значениеFalse
.runserver
больше не поддерживаетpyinotify
(заменен на Watchman).Агрегатные функции
Avg
,StdDev
иVariance
теперь возвращаютDecimal
вместоfloat
, когда на вход подаетсяDecimal
.Тесты не будут работать на SQLite, если приложения без миграций имеют отношения к приложениям с миграциями. Это было документированным ограничением с тех пор, как миграции были добавлены в Django 1.7, но теперь это происходит более надежно. Вы увидите, что тесты завершаются с ошибками типа
no such table: <app_label>_<model>
. Это наблюдалось в нескольких сторонних приложениях, которые имели модели в тестах без миграций. Вы должны добавить миграции для таких моделей.Предоставление целого числа в аргументе
key
дляcache.delete()
илиcache.get()
теперь приводит к возникновениюValueError
.Уравнения множественного числа для некоторых языков изменены, так как включены последние версии от Transifex.
Примечание
В Django 2.2.12 была добавлена возможность обрабатывать файлы
.po
, содержащие различные множественные числа для одного и того же языка.
Функции, устаревшие в версии 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__'
.