Примечания к выпуску 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 переписан с учетом нового синтаксиса и более подробной информации.

Mobile-friendly 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() на кверисете с нарезкой приводит к неожиданным результатам из-за того, что нарезка применяется после переупорядочения. Теперь это запрещено, например:

>>> 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.
Вернуться на верх