Примечания к выпуску Django 2.0

2 декабря 2017

Добро пожаловать в Django 2.0!

Эти заметки о выпуске охватывают new features, а также некоторые backwards incompatible changes, о которых вы захотите знать при переходе с Django 1.11 или более ранней версии. Мы dropped some features, которые достигли конца своего цикла устаревания, и мы begun the deprecation process for some features.

Этот выпуск начинает использование в Django символа loose form of semantic versioning, но в нем нет никаких серьезных изменений, несовместимых с обратной стороной, которые можно было бы ожидать от выпуска 2.0. Обновление не потребует больших усилий, чем предыдущие релизы.

См. руководство Как обновить Django до более новой версии, если вы обновляете существующий проект.

Совместимость с Python

Django 2.0 поддерживает Python 3.4, 3.5, 3.6 и 3.7. Мы настоятельно рекомендуем и официально поддерживаем только последний выпуск каждой серии.

Серия Django 1.11.x является последней, поддерживающей Python 2.7.

Django 2.0 станет последней серией релизов с поддержкой Python 3.4. Если вы планируете развертывание Python 3.4 после окончания срока службы Django 2.0 (апрель 2019 года), остановитесь на Django 1.11 LTS (поддерживается до апреля 2020 года). Однако обратите внимание, что окончание срока службы Python 3.4 приходится на март 2019 года.

Поддержка сторонних библиотек для старых версий Django

После выхода Django 2.0 мы предлагаем авторам сторонних приложений отказаться от поддержки всех версий Django, предшествующих 1.11. В это время вы должны иметь возможность запускать тесты вашего пакета, используя python -Wd, чтобы предупреждения об устаревании не появлялись. После исправления предупреждений об устаревании ваше приложение должно быть совместимо с Django 2.0.

Что нового в Django 2.0

Упрощенный синтаксис маршрутизации URL

Новая функция django.urls.path() позволяет использовать более простой, более читаемый синтаксис маршрутизации URL. Например, этот пример из предыдущих релизов Django:

url(r"^articles/(?P<year>[0-9]{4})/$", views.year_archive),

можно записать так:

path("articles/<int:year>/", views.year_archive),

Новый синтаксис поддерживает принудительное определение типа параметров URL. В примере представление будет получать аргумент ключевого слова year как целое число, а не как строку. Кроме того, в переписанном примере URL, которые будут соответствовать, немного менее ограничены. Например, год 10000 теперь будет соответствовать, поскольку целые числа года не ограничиваются длиной ровно в четыре цифры, как в регулярном выражении.

Функция django.conf.urls.url() из предыдущих версий теперь доступна как django.urls.re_path(). Старое расположение остается для обратной совместимости, без неизбежного обесценивания. Старая функция django.conf.urls.include() теперь импортируется из django.urls, так что вы можете использовать from django.urls import include, path, re_path в ваших URLconfs.

Документ Диспетчер URL переписан с учетом нового синтаксиса и более подробной информации.

Удобный для мобильных устройств contrib.admin

Админка теперь отзывчивая и поддерживает все основные мобильные устройства. В старых браузерах может наблюдаться различный уровень плавной деградации.

Оконные выражения

Новое выражение Window позволяет добавить к кверисетам условие OVER. В выражении можно использовать window functions и aggregate functions.

Незначительные особенности

django.contrib.admin

django.contrib.auth

  • Число итераций по умолчанию для хешера паролей PBKDF2 увеличено с 36 000 до 100 000.

django.contrib.gis

  • Добавлена поддержка MySQL для функций AsGeoJSON, GeoHash, IsValid, isvalid, и distance lookups.
  • Добавлены функции Azimuth и LineLocatePoint, поддерживаемые в PostGIS и SpatiaLite.
  • Любой GEOSGeometry, импортированный из GeoJSON, теперь имеет установленный SRID.
  • Добавлен атрибут OSMWidget.default_zoom для настройки уровня масштабирования карты по умолчанию.
  • Сделал метаданные читаемыми и редактируемыми на растрах с помощью атрибутов metadata, info и metadata.
  • Позволяет передавать специфичные для драйвера параметры создания объектам GDALRaster с помощью papsz_options.
  • Позволяет создавать GDALRaster объекты во внутренней виртуальной файловой системе GDAL. Растры теперь могут быть created from and converted to binary data в памяти.
  • Новый метод GDALBand.color_interp() возвращает интерпретацию цвета для полосы.

django.contrib.postgres

  • Новый аргумент distinct для ArrayAgg определяет, будут ли конкатенированные значения различаться.
  • Новая функция базы данных RandomUUID возвращает UUID версии 4. Она требует использования расширения PostgreSQL pgcrypto, которое может быть активировано с помощью новой операции миграции CryptoExtension.
  • django.contrib.postgres.indexes.GinIndex теперь поддерживает параметры fastupdate и gin_pending_list_limit.
  • Новый класс GistIndex позволяет создавать GiST индексы в базе данных. Новая операция миграции BtreeGistExtension устанавливает расширение btree_gist для добавления поддержки классов операторов, которые не являются встроенными.
  • inspectdb теперь может интроспектировать JSONField и различные RangeFields (django.contrib.postgres должен быть в INSTALLED_APPS).

django.contrib.sitemaps

  • Добавлен аргумент ключевого слова protocol в конструктор GenericSitemap.

Кэш

  • cache.set_many() теперь возвращает список ключей, которые не удалось вставить. Для встроенных бэкендов неудачная вставка может произойти только на memcached.

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

  • File.open() можно использовать в качестве менеджера контекста, например, with file.open() as f:.

Формы

  • Новые аргументы date_attrs и time_attrs для SplitDateTimeWidget и SplitHiddenDateTimeWidget позволяют указывать различные HTML-атрибуты для DateInput и TimeInput (или скрытых) субвиджетов.
  • Новый метод Form.errors.get_json_data() возвращает ошибки формы в виде словаря, пригодного для включения в JSON-ответ.

Общие представления

Команды управления

  • inspectdb теперь переводит беззнаковые целочисленные столбцы MySQL в PositiveIntegerField или PositiveSmallIntegerField.
  • Новая опция makemessages --add-location управляет форматом комментариев в файлах .po.
  • loaddata теперь может read from stdin.
  • Новая опция diffsettings --output позволяет форматировать вывод в унифицированном формате diff.
  • В Oracle, inspectdb теперь может интроспектировать AutoField, если столбец создан как столбец идентичности.
  • В MySQL, dbshell теперь поддерживает TLS сертификаты на стороне клиента.

Миграции

Модели

  • Новая функция базы данных StrIndex находит начальный индекс строки внутри другой строки.
  • В Oracle, AutoField и BigAutoField теперь создаются как identity columns.
  • Новый параметр chunk_size QuerySet.iterator() управляет количеством строк, извлекаемых клиентом базы данных Python при потоковой передаче результатов из базы данных. Для баз данных, которые не поддерживают курсоры на стороне сервера, он управляет количеством результатов, которые Django получает от адаптера базы данных.
  • QuerySet.earliest(), QuerySet.latest() и Meta.get_latest_by теперь позволяют упорядочивать по нескольким полям.
  • Добавлена функция ExtractQuarter для извлечения квартала из DateField и DateTimeField, и выставления его через поиск quarter.
  • Добавлена функция TruncQuarter для усечения DateField и DateTimeField до первого дня квартала.
  • Добавлен параметр db_tablespace для индексов на основе классов.
  • Если база данных поддерживает встроенное поле длительности (Oracle и PostgreSQL), Extract теперь работает с DurationField.
  • Добавлен аргумент of к QuerySet.select_for_update(), поддерживаемый в PostgreSQL и Oracle, для блокировки только строк из определенных таблиц, а не всех выбранных таблиц. Это может быть полезно, особенно когда select_for_update() используется в сочетании с select_related().
  • Новый параметр field_name QuerySet.in_bulk() позволяет получать результаты на основе любого уникального поля модели.
  • CursorWrapper.callproc() теперь принимает необязательный словарь параметров ключевых слов, если бэкенд поддерживает эту возможность. Из встроенных бэкендов Django только Oracle поддерживает эту возможность.
  • Новый метод connection.execute_wrapper() позволяет installing wrappers around execution of database queries.
  • Новый аргумент filter для встроенных агрегатов позволяет adding different conditionals выполнять несколько агрегаций по одним и тем же полям или отношениям.
  • Добавлена поддержка выражений в Meta.ordering.
  • Новый параметр named в QuerySet.values_list() позволяет получать результаты в виде именованных кортежей.
  • Новый класс FilteredRelation позволяет добавлять к кверисетам условие ON.

Пагинация

  • Добавлено Paginator.get_page() для обеспечения документированного шаблона обработки недействительных номеров страниц.

Запросы и ответы

  • Веб-сервер runserver поддерживает HTTP 1.1.

Шаблоны

  • Чтобы повысить полезность Engine.get_default() в сторонних приложениях, теперь он возвращает первый двигатель, если несколько двигателей DjangoTemplates настроены в TEMPLATES, а не поднимает ImproperlyConfigured.
  • Пользовательские теги шаблонов теперь могут принимать аргументы, содержащие только ключевые слова.

Тесты

Валидаторы

  • Новый ProhibitNullCharactersValidator запрещает ввод нулевого символа в поле формы CharField и его подклассах. Ввод нулевого символа был замечен инструментами сканирования уязвимостей. Большинство баз данных молча отбрасывают нулевые символы, но psycopg2 2.7+ вызывает исключение при попытке сохранить нулевой символ в поле char/text в PostgreSQL.

Изменения в версии 2.0, несовместимые с обратными изменениями

Удалена поддержка байтовых строк в некоторых местах

Для поддержки родных строк Python 2 старые версии Django должны были принимать как байтовые строки, так и строки Unicode. Теперь, когда поддержка Python 2 прекращена, байтовые строки должны встречаться только на границах ввода/вывода (обработка двоичных полей или HTTP-потоков, например). Возможно, вам придется обновить свой код, чтобы ограничить использование байтовых строк до минимума, так как Django больше не принимает байтовые строки в определенных путях кода. Опция Python -b может помочь обнаружить эту ошибку в вашем коде.

Например, reverse() теперь использует str() вместо force_text() для когеренции получаемых args и kwargs перед их помещением в URL. Для байтовых строк это создает строку с нежелательным префиксом b, а также дополнительными кавычками (str(b'foo') становится "b'foo'"). Чтобы адаптироваться, вызовите decode() на байтовой строке перед передачей ее в reverse().

API бэкенда базы данных

В этом разделе описаны изменения, которые могут потребоваться в бэкендах баз данных сторонних производителей.

  • Методы DatabaseOperations.datetime_cast_date_sql(), datetime_cast_time_sql(), datetime_trunc_sql(), datetime_extract_sql() и date_interval_sql() теперь возвращают только SQL для выполнения операции вместо SQL и списка параметров.
  • Сторонние бэкенды баз данных должны добавить атрибут DatabaseWrapper.display_name с именем базы данных, с которой работает ваш бэкенд. Django может использовать его в различных сообщениях, например, при проверке системы.
  • Первым аргументом SchemaEditor._alter_column_type_sql() теперь является model, а не table.
  • Первым аргументом SchemaEditor._create_index_name() теперь является table_name, а не model.
  • Чтобы включить поддержку FOR UPDATE OF, установите значение DatabaseFeatures.has_select_for_update_of = True. Если база данных требует, чтобы аргументами OF были столбцы, а не таблицы, установите DatabaseFeatures.select_for_update_of_column = True.
  • Чтобы включить поддержку выражений Window, установите DatabaseFeatures.supports_over_clause в значение True. Возможно, вам потребуется настроить методы DatabaseOperations.window_start_rows_start_end() и/или window_start_range_start_end().
  • Бэкенды баз данных сторонних производителей должны добавить атрибут DatabaseOperations.cast_char_field_without_max_length с типом данных базы данных, который будет использоваться в функции Cast для CharField, если аргумент max_length не предоставлен.
  • Первым аргументом DatabaseCreation._clone_test_db() и get_test_db_clone_settings() теперь является suffix, а не number (на случай, если вы захотите переименовать сигнатуры в своем бэкенде для согласованности). django.test также теперь передает эти значения как строки, а не как целые числа.
  • Сторонние бэкенды баз данных должны добавить метод DatabaseIntrospection.get_sequences(), основанный на заглушке в BaseDatabaseIntrospection.

Прекращена поддержка Oracle 11.2

Окончание поддержки Oracle 11.2 приходится на декабрь 2020 года. Django 1.11 будет поддерживаться до апреля 2020 года, что почти достигает этой даты. Django 2.0 официально поддерживает Oracle 12.1+.

Уровень изоляции MySQL по умолчанию - read committed

Уровень изоляции MySQL по умолчанию, repeatable read, может привести к потере данных при типичном использовании Django. Для предотвращения этого и для согласованности с другими базами данных, уровнем изоляции по умолчанию теперь является read committed. При необходимости вы можете использовать настройку DATABASES для use a different isolation level.

AbstractUser.last_name max_length увеличено до 150

В комплект входит миграция для django.contrib.auth.models.User.last_name. Если у вас есть пользовательская модель пользователя, наследующая от AbstractUser, вам необходимо создать и применить миграцию базы данных для вашей модели пользователя.

Если вы хотите сохранить ограничение в 30 символов для фамилий, используйте пользовательскую форму:

from django.contrib.auth.forms import UserChangeForm


class MyUserChangeForm(UserChangeForm):
    last_name = forms.CharField(max_length=30, required=False)

Если вы хотите сохранить это ограничение в админке при редактировании пользователей, установите UserAdmin.form для использования этой формы:

from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User


class MyUserAdmin(UserAdmin):
    form = MyUserChangeForm


admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)

QuerySet.reverse() и last() запрещены после нарезки

Вызов QuerySet.reverse() или last() на нарезанном queryset приводит к неожиданным результатам из-за того, что нарезка применяется после переупорядочивания. Теперь это запрещено, например:

>>> Model.objects.all()[:2].reverse()
Traceback (most recent call last):
...
TypeError: Cannot reverse a query once a slice has been taken.

Поля формы больше не принимают необязательные аргументы в качестве позиционных аргументов

Для предотвращения ошибок во время выполнения из-за неправильного упорядочивания аргументов поля формы, необязательные аргументы встроенных полей формы больше не принимаются в качестве позиционных аргументов. Например:

forms.IntegerField(25, 10)

вызывает исключение и должен быть заменен на:

forms.IntegerField(max_value=25, min_value=10)

call_command() проверяет полученные параметры

call_command() теперь проверяет, что парсер аргументов вызываемой команды определяет все опции, переданные в call_command().

Для пользовательских команд управления, которые используют опции, не созданные с помощью parser.add_argument(), добавьте атрибут stealth_options в команду:

class MyCommand(BaseCommand):
    stealth_options = ("option_name", ...)

Индексы больше не принимают позиционные аргументы

Например:

models.Index(["headline", "-pub_date"], "index_name")

вызывает исключение и должен быть заменен на:

models.Index(fields=["headline", "-pub_date"], name="index_name")

Ограничения внешнего ключа теперь включены в SQLite

Это отобразится как обратно несовместимое изменение (IntegrityError: FOREIGN KEY constraint failed) при попытке сохранить существующий экземпляр модели, нарушающий ограничение внешнего ключа.

Внешние ключи теперь создаются с помощью DEFERRABLE INITIALLY DEFERRED вместо DEFERRABLE IMMEDIATE. Таким образом, таблицы, возможно, придется перестроить, чтобы воссоздать внешние ключи с новым определением, особенно если вы используете шаблон, подобный этому:

from django.db import transaction

with transaction.atomic():
    Book.objects.create(author_id=1)
    Author.objects.create(id=1)

Если вы не пересоздадите внешний ключ как DEFERRED, то первый create() будет неудачным теперь, когда ограничения внешнего ключа соблюдаются.

Сначала создайте резервную копию вашей базы данных! После обновления до Django 2.0 вы можете восстановить таблицы с помощью скрипта, подобного этому:

from django.apps import apps
from django.db import connection

for app in apps.get_app_configs():
    for model in app.get_models(include_auto_created=True):
        if model._meta.managed and not (model._meta.proxy or model._meta.swapped):
            for base in model.__bases__:
                if hasattr(base, "_meta"):
                    base._meta.local_many_to_many = []
            model._meta.local_many_to_many = []
            with connection.schema_editor() as editor:
                editor._remake_table(model)

Этот скрипт не прошел обширного тестирования и нуждается в адаптации для различных случаев, таких как несколько баз данных. Не стесняйтесь вносить улучшения.

Кроме того, из-за ограничения SQLite на изменение таблиц запрещено выполнять операции RenameModel и RenameField над моделями или полями, на которые ссылаются другие модели в транзакции. Для того чтобы миграции, содержащие эти операции, могли быть применены, необходимо установить атрибут Migration.atomic в значение False.

Разное

  • Класс SessionAuthenticationMiddleware удален. Он не предоставлял никакой функциональности, поскольку в Django 1.10 аутентификация сессии включена безусловно.

  • Обработчики ошибок HTTP по умолчанию (handler404 и т.д.) теперь являются вызываемыми ссылками вместо пунктирных строк путей Python. Django отдает предпочтение вызываемым ссылкам, так как они обеспечивают лучшую производительность и отладку.

  • RedirectView больше не заглушает NoReverseMatch, если pattern_name не существует.

  • Когда USE_L10N выключен, FloatField и DecimalField теперь соблюдают DECIMAL_SEPARATOR и THOUSAND_SEPARATOR при проверке. Например, с настройками:

    USE_L10N = False
    USE_THOUSAND_SEPARATOR = True
    DECIMAL_SEPARATOR = ","
    THOUSAND_SEPARATOR = "."
    

    ввод "1.345" теперь преобразуется в 1345 вместо 1.345.

  • Подклассы AbstractBaseUser больше не обязаны реализовывать get_short_name() и get_full_name(). (Базовые реализации, вызывающие NotImplementedError, удалены.) django.contrib.admin использует эти методы, если они реализованы, но не требует их. Сторонние приложения, использующие эти методы, могут захотеть принять аналогичный подход.

  • Параметры формата FIRST_DAY_OF_WEEK и NUMBER_GROUPING теперь сохраняются как целые числа в выводах представлений JavaScript и JSON i18n.

  • assertNumQueries() теперь игнорирует запросы конфигурации соединения. Ранее, если тест открывал новое соединение с базой данных, эти запросы могли быть включены в подсчет assertNumQueries().

  • Размер тестового табличного пространства Oracle по умолчанию увеличен с 20M до 50M, а размер авторасширения по умолчанию увеличен с 10M до 25M.

  • Для повышения производительности при потоковой передаче больших наборов результатов из базы данных, QuerySet.iterator() теперь получает 2000 строк за раз вместо 100. Старое поведение может быть восстановлено с помощью параметра chunk_size. Например:

    Book.objects.iterator(chunk_size=100)
    
  • Предоставление неизвестных имен пакетов в аргументе packages представления JavaScriptCatalog теперь вызывает ValueError вместо молчаливого прохождения.

  • Первичный ключ экземпляра модели теперь отображается в методе Model.__str__() по умолчанию, например Question object (1).

  • makemigrations теперь определяет изменения в опции limit_choices_to для поля модели. Добавьте это в существующие миграции или примите автоматически сгенерированную миграцию для полей, использующих эту опцию.

  • Выполнение запросов, требующих automatic spatial transformations, теперь вызывает NotImplementedError на MySQL вместо молчаливого использования нетрансформированных геометрий.

  • django.core.exceptions.DjangoRuntimeWarning удален. Он использовался только в бэкенде кэша в качестве промежуточного класса при наследовании CacheKeyWarning от RuntimeWarning.

  • Переименовал BaseExpression._output_field в output_field. Может потребоваться обновление пользовательских выражений.

  • В старых версиях формы и наборы форм объединяли свои Media с виджетом Media путем конкатенации. Теперь объединение пытается preserve the relative order of elements in each list. MediaOrderConflictWarning выдается, если порядок не может быть сохранен.

  • django.contrib.gis.gdal.OGRException удален. Это был псевдоним для GDALException со времен Django 1.8.

  • Поддержка GEOS 3.3.x прекращена.

  • Способ отбора данных для GeometryField изменен для повышения производительности, и в необработанных SQL-запросах эти поля теперь должны быть обернуты в connection.ops.select. Смотрите пример Raw queries note в учебнике по ГИС.

Функции, устаревшие в версии 2.0

context аргумент Field.from_db_value() и Expression.convert_value()

Аргумент context в Field.from_db_value() и Expression.convert_value() не используется, так как это всегда пустой словарь. Сигнатура обоих методов теперь такая:

(self, value, expression, connection)

вместо:

(self, value, expression, connection, context)

Поддержка старой подписи в пользовательских полях и выражениях сохранится до версии Django 3.0.

Разное

  • Модуль django.db.backends.postgresql_psycopg2 устарел в пользу django.db.backends.postgresql. Он является псевдонимом с версии Django 1.9. Это влияет только на код, который импортирует из модуля напрямую. В настройках DATABASES по-прежнему можно использовать 'django.db.backends.postgresql_psycopg2', хотя вы можете упростить этот процесс, используя имя 'django.db.backends.postgresql', добавленное в Django 1.9.
  • django.shortcuts.render_to_response() устарел в пользу django.shortcuts.render(). render() принимает те же аргументы, за исключением того, что он также требует request.
  • Параметр DEFAULT_CONTENT_TYPE устарел. Она плохо взаимодействует со сторонними приложениями и устарела, поскольку HTML5 в основном вытеснил XHTML.
  • HttpRequest.xreadlines() устарел в пользу итерации по запросу.
  • Ключевой аргумент field_name в QuerySet.earliest() и QuerySet.latest() устарел в пользу передачи имен полей в качестве аргументов. Пишите .earliest('pub_date') вместо .earliest(field_name='pub_date').

Функции, удаленные в версии 2.0

Эти функции достигли конца своего цикла устаревания и будут удалены в Django 2.0.

Подробнее об этих изменениях, в том числе о том, как удалить использование этих функций, смотрите Функции, устаревшие в версии 1.9.

  • Аргумент weak в django.dispatch.signals.Signal.disconnect() удаляется.
  • django.db.backends.base.BaseDatabaseOperations.check_aggregate_support() удаляется.
  • Пакет django.forms.extras удаляется.
  • Помощник assignment_tag удаляется.
  • Аргумент host в SimpleTestCase.assertsRedirects() удален. Также удален слой совместимости, который позволяет абсолютным URL-адресам считаться равными относительным, когда путь идентичен.
  • Field.rel и Field.remote_field.to удаляются.
  • Аргумент on_delete для ForeignKey и OneToOneField теперь требуется в моделях и миграциях. Подумайте о сокращении миграций, чтобы их было меньше для обновления.
  • django.db.models.fields.add_lazy_relation() удаляется.
  • Когда включена поддержка часовых поясов, бэкенды баз данных, которые не поддерживают часовые пояса, больше не конвертируют известные времена дат в наивные значения в UTC, когда такие значения передаются в качестве параметров в SQL-запросы, выполняемые вне ORM, например, с помощью cursor.execute().
  • django.contrib.auth.tests.utils.skipIfCustomUser() удаляется.
  • Классы GeoManager и GeoQuerySet удалены.
  • Модуль django.contrib.gis.geoip удаляется.
  • Убрана проверка supports_recursion для загрузчиков шаблонов:
    • django.template.engine.Engine.find_template()
    • django.template.loader_tags.ExtendsNode.find_template()
    • django.template.loaders.base.Loader.supports_recursion()
    • django.template.loaders.cached.Loader.supports_recursion()
  • Методы загрузчика шаблонов load_template и load_template_sources удалены.
  • Аргумент template_dirs для загрузчиков шаблонов удален:
    • django.template.loaders.base.Loader.get_template()
    • django.template.loaders.cached.Loader.cache_key()
    • django.template.loaders.cached.Loader.get_template()
    • django.template.loaders.cached.Loader.get_template_sources()
    • django.template.loaders.filesystem.Loader.get_template_sources()
  • django.template.loaders.base.Loader.__call__() удаляется.
  • Удалена поддержка пользовательских представлений ошибок, которые не принимают параметр exception.
  • Атрибут mime_type из django.utils.feedgenerator.Atom1Feed и django.utils.feedgenerator.RssFeed удален.
  • Аргумент app_name в include() удаляется.
  • Удалена поддержка передачи 3-кортежа (включая admin.site.urls) в качестве первого аргумента в include().
  • Устранена поддержка установки пространства имен экземпляра URL без пространства имен приложения.
  • Field._get_val_from_obj() удаляется.
  • django.template.loaders.eggs.Loader удаляется.
  • Параметр current_app к представлениям на основе функций contrib.auth удален.
  • Аргумент ключевого слова callable_obj в SimpleTestCase.assertRaisesMessage() удаляется.
  • Убрана поддержка атрибута allow_tags для методов ModelAdmin.
  • Аргумент ключевого слова enclosure в SyndicationFeed.add_item() удаляется.
  • Псевдонимы django.template.loader.LoaderOrigin и django.template.base.StringOrigin для django.template.base.Origin удалены.

Подробнее об этих изменениях смотрите Функции, устаревшие в версии 1.10.

  • Опция makemigrations --exit удалена.
  • Устранена поддержка прямого присвоения обратному внешнему ключу или отношению «многие-ко-многим».
  • Методы get_srid() и set_srid() из django.contrib.gis.geos.GEOSGeometry удалены.
  • Методы get_x(), set_x(), get_y(), set_y(), get_z() и set_z() из django.contrib.gis.geos.Point удалены.
  • Методы get_coords() и set_coords() из django.contrib.gis.geos.Point удалены.
  • Свойство cascaded_union из django.contrib.gis.geos.MultiPolygon удалено.
  • django.utils.functional.allow_lazy() удаляется.
  • Опция shell --plain удалена.
  • Модуль django.core.urlresolvers удаляется в пользу его нового местоположения django.urls.
  • CommaSeparatedIntegerField удален, за исключением поддержки в исторических миграциях.
  • Метод шаблона Context.has_key() удален.
  • Удалена поддержка методов django.core.files.storage.Storage.accessed_time(), created_time() и modified_time().
  • Устранена поддержка поиска запросов с использованием имени модели, когда установлено значение Meta.default_related_name.
  • Убран поиск MySQL __search.
  • Удален шим для поддержки пользовательских классов связанных менеджеров без метода _apply_rel_filters().
  • Использование User.is_authenticated() и User.is_anonymous() в качестве методов, а не свойств, больше не поддерживается.
  • Атрибут Model._meta.virtual_fields удаляется.
  • Аргументы ключевых слов virtual_only в Field.contribute_to_class() и virtual в Model._meta.add_field() удаляются.
  • Представления javascript_catalog() и json_catalog() удалены.
  • django.contrib.gis.utils.precision_wkt() удаляется.
  • При многотабличном наследовании удалено неявное повышение OneToOneField до parent_link.
  • Поддержка Widget._format_value() удалена.
  • Методы FileField get_directory_name() и get_filename() удалены.
  • Функция mark_for_escaping() и используемые ею классы: EscapeData, EscapeBytes, EscapeText, EscapeString и EscapeUnicode удалены.
  • Фильтр escape теперь использует django.utils.html.conditional_escape().
  • Manager.use_for_related_fields удаляется.
  • Наследование модели Manager следует правилам наследования MRO. Требование использовать Meta.manager_inheritance_from_future для выбора поведения удалено.
  • Устранена поддержка старого стиля промежуточного ПО, использующего settings.MIDDLEWARE_CLASSES.
Вернуться на верх