Примечания к выпуску Django 3.0¶
Декабрь 2, 2019
Добро пожаловать в Django 3.0!
Эти заметки о выпуске охватывают new features, а также некоторые backwards incompatible changes, о которых вы захотите знать при переходе с Django 2.2 или более ранней версии. Мы dropped some features, которые достигли конца своего цикла устаревания, и мы begun the deprecation process for some features.
См. руководство Как обновить Django до более новой версии, если вы обновляете существующий проект.
Совместимость с Python¶
Django 3.0 поддерживает Python 3.6, 3.7, 3.8 и 3.9 (начиная с версии 3.0.11). Мы настоятельно рекомендуем и официально поддерживаем только последний выпуск каждой серии.
Серия Django 2.2.x является последней, поддерживающей Python 3.5.
Поддержка сторонних библиотек для старых версий Django¶
После выхода Django 3.0 мы предлагаем авторам сторонних приложений отказаться от поддержки всех версий Django, предшествующих 2.2. В это время вы должны иметь возможность запускать тесты вашего пакета, используя python -Wd
, чтобы появились предупреждения об устаревании. После исправления предупреждений об износе ваше приложение должно быть совместимо с Django 3.0.
Что нового в Django 3.0¶
Поддержка MariaDB¶
Django теперь официально поддерживает MariaDB 10.1 и выше. Более подробную информацию смотрите в MariaDB notes.
Поддержка ASGI¶
Django 3.0 начинает наш путь к тому, чтобы сделать Django полностью async-совместимым, предоставляя поддержку запуска в качестве приложения ASGI.
Это дополнение к существующей поддержке WSGI. Django намерен поддерживать оба варианта в обозримом будущем. Однако, функции Async будут доступны только для приложений, работающих под ASGI.
На данном этапе поддержка async применяется только к внешнему приложению ASGI. Внутри все остается синхронным. Асинхронное промежуточное ПО, представления и т.д. пока не поддерживаются. Тем не менее, вы можете использовать ASGI промежуточное ПО вокруг приложения Django, что позволит вам комбинировать Django с другими ASGI-фреймворками.
Нет необходимости переключать свои приложения, если вы не хотите начать экспериментировать с асинхронным кодом, но у нас есть documentation on deploying with ASGI, если вы хотите узнать больше.
Обратите внимание, что в качестве побочного эффекта этого изменения Django теперь знает об асинхронных циклах событий и будет блокировать вызов кода, помеченного как «async unsafe» - например, операций ORM - из асинхронного контекста. Если вы раньше использовали Django из асинхронного кода, это может сработать, если вы делали это неправильно. Если вы видите ошибку SynchronousOnlyOperation
, то внимательно изучите свой код и переместите все операции с базой данных в синхронный дочерний поток.
Ограничения исключения в PostgreSQL¶
Новый класс ExclusionConstraint
позволяет добавлять ограничения исключения в PostgreSQL. Ограничения добавляются в модели с помощью опции Meta.constraints
.
Фильтр выражений¶
Выражения, выводящие BooleanField
, теперь можно использовать непосредственно в фильтрах QuerySet
, без необходимости сначала аннотировать, а затем фильтровать по аннотации.
Перечисления для выбора поля модели¶
Пользовательские типы перечислений TextChoices
, IntegerChoices
и Choices
теперь доступны как способ определения Field.choices
. Типы TextChoices
и IntegerChoices
предусмотрены для текстовых и целочисленных полей. Класс Choices
позволяет определить совместимое перечисление для других конкретных типов данных. Эти пользовательские типы перечислений поддерживают человекочитаемые метки, которые могут быть переведены и доступны через свойство перечисления или его членов. Более подробную информацию и примеры смотрите в Enumeration types.
Незначительные особенности¶
django.contrib.admin
¶
- Добавлена поддержка атрибута
admin_order_field
для свойств вModelAdmin.list_display
. - Новый метод
ModelAdmin.get_inlines()
позволяет указывать инлайны на основе запроса или экземпляра модели. - Библиотека Select2 обновлена с версии 4.0.3 до 4.0.7.
- jQuery обновлен с версии 3.3.1 до 3.4.1.
django.contrib.auth
¶
- Новый атрибут
reset_url_token
вPasswordResetConfirmView
позволяет указать параметр токена, отображаемый как компонент URL-адресов сброса пароля. - Добавлен класс
BaseBackend
для облегчения настройки бэкендов аутентификации. - Добавлен метод
get_user_permissions()
, зеркально отражающий существующий методget_group_permissions()
. - Добавлен HTML атрибут
autocomplete
к виджетам полей имени пользователя, электронной почты и пароля вdjango.contrib.auth.forms
для лучшего взаимодействия с менеджерами паролей в браузере. createsuperuser
теперь возвращается к переменным окружения для пароля и обязательных полей, когда соответствующий аргумент командной строки не предоставлен в неинтерактивном режиме.REQUIRED_FIELDS
теперь поддерживаетManyToManyField
s.- Новый метод
UserManager.with_perm()
возвращает пользователей, имеющих указанное разрешение. - Количество итераций по умолчанию для хешера паролей PBKDF2 увеличено со 150 000 до 180 000.
django.contrib.gis
¶
- Позволяет функциям пространственного поиска MySQL работать с реальной геометрией. Предыдущая поддержка была ограничена ограничивающими рамками.
- Добавлена функция
GeometryDistance
, поддерживаемая в PostGIS. - Добавлена поддержка блока
furlong
вDistance
. - Настройка
GEOIP_PATH
теперь поддерживаетpathlib.Path
. - Класс
GeoIP2
теперь принимаетpathlib.Path
path
.
django.contrib.postgres
¶
- Новый
RangeOperators
помогает избежать опечаток в операторах SQL, которые могут использоваться вместе сRangeField
. - Новое выражение
RangeBoundary
представляет границы диапазона. - Новые классы
AddIndexConcurrently
иRemoveIndexConcurrently
позволяют создавать и удалять индексыCONCURRENTLY
на PostgreSQL.
django.contrib.sessions
¶
- Новый метод
get_session_cookie_age()
позволяет динамически указывать возраст куки сессии.
django.contrib.syndication
¶
- Добавлен атрибут
language
class кdjango.contrib.syndication.views.Feed
для настройки языка фида. По умолчанию используется значениеget_language()
вместоLANGUAGE_CODE
.
Кэш¶
add_never_cache_headers()
иnever_cache()
теперь добавляют директивуprivate
к заголовкамCache-Control
.
Хранение файлов¶
- Новый метод
Storage.get_alternative_name()
позволяет настроить алгоритм генерации имен файлов, если файл с загружаемым именем уже существует.
Формы¶
- Наборы форм могут управлять виджетом, используемым при заказе форм через
can_order
, устанавливая атрибутordering_widget
или переопределяяget_ordering_widget()
.
Интернационализация¶
- Добавлены параметры
LANGUAGE_COOKIE_HTTPONLY
,LANGUAGE_COOKIE_SAMESITE
иLANGUAGE_COOKIE_SECURE
для установки флаговHttpOnly
,SameSite
иSecure
для языковых файлов cookie. Значения по умолчанию этих параметров сохраняют предыдущее поведение. - Добавлена поддержка и переводы для узбекского языка.
Ведение журнала¶
- Новый параметр
reporter_class
вAdminEmailHandler
позволяет подклассуdjango.views.debug.ExceptionReporter
настроить текст трассировки, отправляемый на сайтADMINS
, когдаDEBUG
становитсяFalse
.
Команды управления¶
- Новая опция
compilemessages --ignore
позволяет игнорировать определенные каталоги при поиске.po
файлов для компиляции. showmigrations --list
теперь показывает применяемые времена дат, когда--verbosity
имеет значение 2 и выше.- В PostgreSQL
dbshell
теперь поддерживает сертификаты TLS на стороне клиента. inspectdb
теперь интроспекцияOneToOneField
, когда внешний ключ имеет ограничение уникального или первичного ключа.- Новая опция
--skip-checks
пропускает проверку системы перед выполнением команды. - Опции
startapp --template
иstartproject --template
теперь поддерживают шаблоны, хранящиеся в архивах XZ (.tar.xz
,.txz
) и LZMA (.tar.lzma
,.tlz
).
Модели¶
Добавлены функции хэш-базы данных
MD5
,SHA1
,SHA224
,SHA256
,SHA384
иSHA512
.Добавлена функция базы данных
Sign
.Новый параметр
is_dst
функций базы данныхTrunc
определяет обработку несуществующих и неоднозначных дат.connection.queries
теперь показываетCOPY … TO
утверждения на PostgreSQL.FilePathField
теперь принимает вызов дляpath
.Разрешенная симметричная промежуточная таблица для самореферентного
ManyToManyField
.Атрибуты
name
CheckConstraint
,UniqueConstraint
иIndex
теперь поддерживают интерполяцию метки приложения и класса с помощью держателей'%(app_label)s'
и'%(class)s'
.Новый атрибут
Field.descriptor_class
позволяет полям модели настраивать поведение get и set, переопределяя их descriptors.Добавлено
SmallAutoField
, которое действует подобноAutoField
, за исключением того, что оно допускает только значения ниже определенного (зависящего от базы данных) предела. Значения от1
до32767
безопасны во всех базах данных, поддерживаемых Django.AutoField
,BigAutoField
иSmallAutoField
теперь наследуются отIntegerField
,BigIntegerField
иSmallIntegerField
соответственно. Системные проверки и валидаторы теперь также правильно наследуются.FileField.upload_to
теперь поддерживаетpathlib.Path
.CheckConstraint
теперь поддерживается на MySQL 8.0.16+.Новый метод
allows_group_by_selected_pks_on_model()
вdjango.db.backends.base.BaseDatabaseFeatures
позволяет оптимизировать условияGROUP BY
, чтобы требовать только первичные ключи выбранных моделей. По умолчанию он поддерживается только для управляемых моделей на PostgreSQL.Чтобы включить оптимизацию
GROUP BY
только по первичному ключу для неуправляемых моделей, необходимо подкласс движка базы данных PostgreSQL, переопределив метод features classallows_group_by_selected_pks_on_model()
так, как вам нужно. Пример смотрите в Subclassing the built-in database backends.
Запросы и ответы¶
- Позволяет инициализировать
HttpResponse
содержимымmemoryview
. - Для использования, например, в шаблонах Django,
HttpRequest.headers
теперь позволяет искать с использованием подчеркивания (например,user_agent
) вместо дефиса.
Безопасность¶
X_FRAME_OPTIONS
теперь имеет значение по умолчанию'DENY'
. В старых версиях параметрX_FRAME_OPTIONS
по умолчанию имеет значение'SAMEORIGIN'
. Если ваш сайт использует собственные фреймы, вам необходимо явно установитьX_FRAME_OPTIONS = 'SAMEORIGIN'
, чтобы они продолжали работать.SECURE_CONTENT_TYPE_NOSNIFF
теперь имеет значение по умолчаниюTrue
. Если это включено,SecurityMiddleware
устанавливает заголовок X-Content-Type-Options: nosniff во всех ответах, которые еще не имеют его.SecurityMiddleware
теперь может отправить заголовок Referrer-Policy.
Тесты¶
- Новый аргумент теста
Client
raise_request_exception
позволяет контролировать, должны ли исключения, поднятые во время запроса, также подниматься в тесте. Значение по умолчаниюTrue
для обратной совместимости. Если значениеFalse
и происходит исключение, клиент теста возвращает ответ 500 с атрибутомexc_info
, кортеж, содержащий информацию о произошедшем исключении. - Тесты и тестовые случаи для запуска можно выбирать по шаблону имени теста с помощью новой опции
test -k
. - Сравнение HTML, используемое
assertHTMLEqual()
, теперь рассматривает текст, ссылки на символы и ссылки на сущности, которые ссылаются на один и тот же символ, как эквивалентные. - Django test runner теперь поддерживает режим headless для тестов selenium на поддерживаемых браузерах. Добавьте опцию
--headless
для включения этого режима. - Django test runner теперь поддерживает опции
--start-at
и--start-after
для запуска тестов, начиная с определенного модуля верхнего уровня. - Бегунок тестирования Django теперь поддерживает опцию
--pdb
для порождения отладчика при каждой ошибке или сбое.
Изменения в версии 3.0, несовместимые с обратными изменениями¶
Model.save()
при предоставлении значения по умолчанию для первичного ключа¶
Model.save()
больше не пытается найти строку при сохранении нового экземпляра Model
, если для первичного ключа задано значение по умолчанию, и всегда выполняет один запрос INSERT
. В старых версиях Django Model.save()
выполнял либо INSERT
, либо UPDATE
в зависимости от того, существует ли строка или нет.
Это делает вызов Model.save()
при предоставлении значения первичного ключа по умолчанию эквивалентным передаче force_insert=True в save()
модели. Попытки использовать новый экземпляр Model
для обновления существующей строки приведут к ошибке IntegrityError
.
Чтобы обновить существующую модель для определенного значения первичного ключа, используйте метод update_or_create()
или QuerySet.filter(pk=…).update(…)
. Например:
>>> MyModel.objects.update_or_create(pk=existing_pk, defaults={'name': 'new name'})
>>> MyModel.objects.filter(pk=existing_pk).update(name='new name')
API бэкенда базы данных¶
В этом разделе описаны изменения, которые могут потребоваться в бэкендах баз данных сторонних производителей.
- Вторым аргументом
DatabaseIntrospection.get_geometry_type()
теперь является описание строки, а не имя столбца. DatabaseIntrospection.get_field_type()
больше не может возвращать кортежи.- Если база данных может создавать внешние ключи в том же операторе SQL, который добавляет поле, добавьте
SchemaEditor.sql_create_column_inline_fk
с соответствующим SQL; в противном случае установитеDatabaseFeatures.can_create_inline_fk = False
. DatabaseFeatures.can_return_id_from_insert
иcan_return_ids_from_bulk_insert
переименованы вcan_return_columns_from_insert
иcan_return_rows_from_bulk_insert
.- Функции базы данных теперь обрабатывают формат
datetime.timezone
при создании с использованием экземпляровdatetime.timedelta
(например,timezone(timedelta(hours=5))
, который выводил бы'UTC+05:00'
). Сторонние бэкенды должны обрабатывать этот формат при подготовкеDateTimeField
вdatetime_cast_date_sql()
,datetime_extract_sql()
и т.д. - Записи для
AutoField
,BigAutoField
иSmallAutoField
добавлены вDatabaseOperations.integer_field_ranges
для поддержки валидаторов целочисленного диапазона для этих типов полей. Сторонним бэкендам может потребоваться настройка записей по умолчанию. DatabaseOperations.fetch_returned_insert_id()
заменяется наfetch_returned_insert_columns()
, который возвращает список значений, возвращаемых операторомINSERT … RETURNING
, вместо одного значения.DatabaseOperations.return_insert_id()
заменяется наreturn_insert_columns()
, который принимает аргументfields
, представляющий собой итерацию полей, которые будут возвращены после вставки. Обычно это только автоматически генерируемый первичный ключ.
django.contrib.admin
¶
- Сообщения администратора об изменении истории модели теперь предпочитают более читабельные метки полей вместо их названий.
django.contrib.gis
¶
- Удалена поддержка PostGIS 2.1.
- Удалена поддержка SpatiaLite 4.1 и 4.2.
- Удалена поддержка GDAL 1.11 и GEOS 3.4.
Прекращена поддержка PostgreSQL 9.4¶
Поддержка PostgreSQL 9.4 заканчивается в декабре 2019 года. Django 3.0 поддерживает PostgreSQL 9.5 и выше.
Прекращена поддержка Oracle 12.1¶
Поддержка Oracle 12.1 заканчивается в июле 2021 года. Django 2.2 будет поддерживаться до апреля 2022 года. Django 3.0 официально поддерживает Oracle 12.2 и 18c.
Удалены частные API совместимости с Python 2¶
Хотя поддержка Python 2 была удалена в Django 2.0, некоторые частные API не были удалены из Django, чтобы сторонние приложения могли продолжать использовать их до окончания срока службы Python 2.
Поскольку мы ожидаем, что приложения откажутся от совместимости с Python 2 при добавлении поддержки Django 3.0, мы удаляем эти API на данный момент.
django.test.utils.str_prefix()
- В Python 3 у строк нет префиксов „u“.django.test.utils.patch_logger()
- Вместо этого используйтеunittest.TestCase.assertLogs()
.django.utils.lru_cache.lru_cache()
- Псевдонимfunctools.lru_cache()
.django.utils.decorators.available_attrs()
- Эта функция возвращаетfunctools.WRAPPER_ASSIGNMENTS
.django.utils.decorators.ContextDecorator
- Псевдонимcontextlib.ContextDecorator
.django.utils._os.abspathu()
- Псевдонимos.path.abspath()
.django.utils._os.upath()
иnpath()
- Эти функции ничего не делают на Python 3.django.utils.six
- Удалить использование этой вендорной библиотеки или переключиться на six.django.utils.encoding.python_2_unicode_compatible()
- Псевдонимsix.python_2_unicode_compatible()
.django.utils.functional.curry()
- Используйтеfunctools.partial()
илиfunctools.partialmethod
. См. 5b1c389603a353625ae1603ba345147356336afb.django.utils.safestring.SafeBytes
- Не используется со времен Django 2.0.
Новое значение по умолчанию для параметра FILE_UPLOAD_PERMISSIONS
¶
В старых версиях параметр FILE_UPLOAD_PERMISSIONS
по умолчанию имеет значение None
. При значении по умолчанию FILE_UPLOAD_HANDLERS
это приводит к тому, что загруженные файлы имеют разные разрешения в зависимости от их размера и используемого обработчика загрузки.
FILE_UPLOAD_PERMISSIONS
теперь по умолчанию используется 0o644
, чтобы избежать этого несоответствия.
Новые значения по умолчанию для параметров безопасности¶
Чтобы сделать проекты Django более безопасными по умолчанию, некоторые параметры безопасности теперь имеют более безопасные значения по умолчанию:
X_FRAME_OPTIONS
теперь по умолчанию'DENY'
.SECURE_CONTENT_TYPE_NOSNIFF
теперь по умолчаниюTrue
.
Подробнее об этих изменениях см. в разделе Что нового Security section выше.
Разное¶
ContentType.__str__()
теперь включает в себяapp_label
модели, чтобы различать модели с одинаковыми именами в разных приложениях.- Поскольку доступ к языку в сессии, а не в cookie, устарел,
LocaleMiddleware
больше не ищет язык пользователя в сессии, аdjango.contrib.auth.logout()
больше не сохраняет язык сессии после выхода из системы. django.utils.html.escape()
теперь используетhtml.escape()
для экранирования HTML. Это преобразует'
в'
вместо прежнего эквивалентного десятичного кода'
.- Опция
django-admin test -k
теперь работает как опцияunittest -k
, а не как сокращение для--keepdb
. - Удалена поддержка
pywatchman
< 1.2.0. urlencode()
теперь кодирует итерируемые значения так, как они есть приdoseq=False
, а не итерирует их, что приводит ее в соответствие с функцией стандартной библиотекиurllib.parse.urlencode()
.- Фильтр шаблона
intword
теперь переводит1.0
как единственное число, а все остальные числовые значения - как множественное. Это может быть неверно для некоторых языков. - Присвоение значения атрибуту
ForeignKey
илиOneToOneField
'_id'
модели теперь отменяет установку соответствующего поля. После этого обращение к полю приведет к запросу. patch_vary_headers()
теперь обрабатывает звездочку'*'
в соответствии с RFC 7231#section-7.1.4, т.е. если список имен полей заголовка содержит звездочку, то заголовокVary
будет состоять из одной звездочки'*'
.- В MySQL 8.0.16+,
PositiveIntegerField
иPositiveSmallIntegerField
теперь включают проверочное ограничение для предотвращения отрицательных значений в базе данных. alias=None
добавляется к сигнатуреExpression.get_group_by_cols()
.RegexPattern
, используемыйre_path()
, больше не возвращает аргументы ключевых слов со значениямиNone
, которые должны быть переданы в представление для необязательных именованных групп, которые отсутствуют.
Функции, устаревшие в версии 3.0¶
django.utils.encoding.force_text()
и smart_text()
¶
Псевдонимы smart_text()
и force_text()
(начиная с Django 2.0) smart_str()
и force_str()
устарели. Игнорируйте это устаревание, если ваш код поддерживает Python 2, так как поведение smart_str()
и force_str()
там отличается.
Разное¶
django.utils.http.urlquote()
,urlquote_plus()
,urlunquote()
иurlunquote_plus()
устарели в пользу функций, псевдонимами которых они являются:urllib.parse.quote()
,quote_plus()
,unquote()
иunquote_plus()
.django.utils.translation.ugettext()
,ugettext_lazy()
,ugettext_noop()
,ungettext()
иungettext_lazy()
устарели в пользу функций, псевдонимами которых они являются:django.utils.translation.gettext()
,gettext_lazy()
,gettext_noop()
,ngettext()
иngettext_lazy()
.- Чтобы ограничить создание сессий и, следовательно, благоприятствовать некоторым стратегиям кэширования,
django.views.i18n.set_language()
перестанет устанавливать язык пользователя в сессии в Django 4.0. Начиная с Django 2.1, язык всегда хранится в cookieLANGUAGE_COOKIE_NAME
. django.utils.text.unescape_entities()
устарел в пользуhtml.unescape()
. Обратите внимание, что в отличие отunescape_entities()
,html.unescape()
оценивает ленивые строки немедленно.- Чтобы избежать возможной путаницы относительно эффективной области применения, частная внутренняя утилита
is_safe_url()
переименована вurl_has_allowed_host_and_scheme()
. То, что URL имеет разрешенный хост и схему, в общем случае не означает, что он «безопасен». Например, он все еще может быть неправильно процитирован. Убедитесь, что вы также используетеiri_to_uri()
в компоненте пути недоверенных URL.
Функции, удаленные в версии 3.0¶
Эти функции достигли конца своего цикла устаревания и будут удалены в Django 3.0.
Подробнее об этих изменениях, в том числе о том, как удалить использование этих функций, смотрите Функции, устаревшие в версии 2.0.
- Модуль
django.db.backends.postgresql_psycopg2
удаляется. django.shortcuts.render_to_response()
удаляется.- Настройка
DEFAULT_CONTENT_TYPE
удаляется. HttpRequest.xreadlines()
удаляется.- Убрана поддержка аргумента
context
вField.from_db_value()
иExpression.convert_value()
. - Аргумент
field_name
ключевого словаQuerySet.earliest()
иlatest()
удаляется.
Подробнее об этих изменениях, в том числе о том, как удалить использование этих функций, смотрите Функции, устаревшие в версии 2.1.
- Функция
ForceRHR
GIS удалена. django.utils.http.cookie_date()
удаляется.- Библиотеки тегов шаблонов
staticfiles
иadmin_static
удалены. django.contrib.staticfiles.templatetags.staticfiles.static()
удаляется.