Примечания к выпуску Django 1.10¶
1 августа 2016 г.
Добро пожаловать в Джанго 1.10!
Эти примечания к выпуску охватывают новые функции, а также некоторые обратно несовместимые изменения, о которых вам следует знать при обновлении с Django 1.9 или более ранних версий. Мы отменили некоторые функции, цикл устаревания которых достиг конца, и мы начали процесс прекращения поддержки некоторых функций.
См. руководство Обновление Django до новой версии, если вы обновляете существующий проект.
Совместимость версий Python¶
Как и Django 1.9, Django 1.10 требует Python 2.7, 3.4 или 3.5. Мы настоятельно рекомендуем и официально поддерживаем только последнюю версию каждой серии.
Что нового в Джанго 1.10¶
Полнотекстовый поиск PostgreSQL¶
django.contrib.postgres теперь включает коллекцию функций базы данных, позволяющую использовать систему полнотекстового поиска. Вы можете выполнять поиск по нескольким полям в своей реляционной базе данных, комбинировать поиск с другими поисками, использовать различные языковые конфигурации и весовые коэффициенты, а также ранжировать результаты по релевантности.
Теперь он также включает поддержку триграмм с использованием поиска trigram_similar и выражений TrigramSimilarity и TrigramDistance.
Промежуточное программное обеспечение нового стиля¶
Введен новый стиль промежуточного программного обеспечения, чтобы решить проблему отсутствия строгого разделения запросов и ответов в старом стиле промежуточного программного обеспечения, описанного в DEP 0005. Вам нужно будет адаптировать старое пользовательское промежуточное программное обеспечение и переключиться с настройки MIDDLEWARE_CLASSES на новую настройку MIDDLEWARE, чтобы воспользоваться преимуществами улучшений.
Официальная поддержка имен пользователей Unicode¶
Модель User в django.contrib.auth изначально принимала в именах пользователей только буквы и цифры ASCII. Хотя это не был преднамеренный выбор, символы Юникода всегда принимались при использовании Python 3.
Валидатор имени пользователя теперь явно принимает символы Юникода по умолчанию только в Python 3.
Пользовательские модели пользователей могут использовать новый ASCIIUsernameValidator или UnicodeUsernameValidator.
Минорные изменения¶
django.contrib.admin¶
Для сайтов, работающих по подпути, URL-адрес по умолчанию для ссылки «Просмотр сайта» <django.contrib.admin.AdminSite.site_url>` в верхней части каждой страницы администрирования теперь будет указывать на
request.META['SCRIPT_NAME'], если он установлен, вместо/.Сообщение об успехе, появляющееся после добавления или редактирования объекта, теперь содержит ссылку на форму изменения объекта.
Весь встроенный JavaScript удален, поэтому вы можете включить HTTP-заголовок Content-Security-Policy, если хотите.
Новый атрибут
InlineModelAdmin.classesпозволяет указывать классы во встроенных наборах полей. Строки с классом «collapse» изначально будут свернуты, а в их заголовке будет небольшая ссылка «показать».Если у пользователя нет разрешения на добавление, блок
object-toolsв списке изменений модели теперь будет отображаться (без кнопки добавления). В данном случае это упрощает добавление пользовательских инструментов.Модель
LogEntryтеперь хранит сообщения об изменениях в структуре JSON, чтобы сообщение можно было динамически перевести с использованием текущего активного языка. Новый метод LogEntry.get_change_message() теперь является предпочтительным способом получения сообщения об изменении.Выбранные объекты для полей в
ModelAdmin.raw_id_fieldsтеперь имеют ссылку на форму изменения объекта.Добавлены варианты «Нет даты» и «Есть дата» для DateFieldListFilter, если поле имеет значение NULL.
Библиотека jQuery, встроенная в админку, обновлена с версии 2.1.4 до 2.2.3.
django.contrib.auth¶
Добавлена поддержка хэша пароля Argon2. Его рекомендуется использовать вместо PBKDF2, однако он не используется по умолчанию, поскольку требует сторонней библиотеки.
Число итераций по умолчанию для хэшера паролей PBKDF2 увеличено на 25%. Это обратно совместимое изменение не повлияет на пользователей, которые создали подкласс django.contrib.auth.hashers.PBKDF2PasswordHasher, чтобы изменить значение по умолчанию.
Представление django.contrib.auth.views.logout() отправляет заголовки «без кэша», чтобы предотвратить проблему, когда Safari кэширует перенаправления и не позволяет пользователю выйти из системы.
В
django.contrib.auth.login()добавлен необязательный аргументbackend, позволяющий использовать его без учетных данных.Новая настройка
LOGOUT_REDIRECT_URLуправляет перенаправлением представленияdjango.contrib.auth.views.logout(), если представление не получает аргументnext_page.Новый параметр redirect_authenticated_user для представления django.contrib.auth.views.login() позволяет перенаправлять аутентифицированных пользователей, посещающих страницу входа.
Новые
AllowAllUsersModelBackendиAllowAllUsersRemoteUserBackendигнорируют значениеUser.is_active, аModelBackendиRemoteUserBackendтеперь отклоняют неактивных пользователей.
django.contrib.gis¶
Поиск расстояния теперь принимает выражения в качестве параметра значения расстояния.
Новое свойство
GEOSGeometry.unary_unionвычисляет объединение всех элементов этой геометрии.Добавлен двоичный предикат
GEOSGeometry.covers().Добавлен метод
GDALBand.statistics()и атрибутыmeanиstd.Добавлена поддержка агрегата
MakeLineи функцииGeoHashв SpatiaLite.Добавлена поддержка функций
Difference,IntersectionиSymDifferenceв MySQL.Добавлена поддержка создания экземпляров пустой геометрии GEOS.
Новые свойства
trimиprecisionWKTWriterпозволяют контролировать вывод дробной части координат в WKT.Добавлены свойства
LineString.closedиMultiLineString.closed.Сериализатор GeoJSON теперь выводит первичный ключ объектов в словаре
properties, если определенные поля не указаны.Добавлена возможность реплицировать входные данные в методе
GDALBand.data(). Данные полосы теперь можно эффективно обновлять повторяющимися значениями.Добавлены функции базы данных
IsValidиMakeValid, а также поискisvalid, все для PostGIS. Это позволяет фильтровать и исправлять неверную геометрию на стороне базы данных.Добавлена поддержка растров для всех пространственных поисков.
django.contrib.postgres¶
Для удобства
HStoreFieldтеперь преобразует свои ключи и значения в строки.
django.contrib.sessions¶
Команда управления
clearsessionsтеперь удаляет файловые сеансы.
django.contrib.sites¶
Модель
Siteтеперь поддерживает естественные ключи.
django.contrib.staticfiles¶
Тег шаблона
staticтеперь используетdjango.contrib.staticfiles, если он находится вINSTALLED_APPS. Это особенно полезно для сторонних приложений, которые теперь всегда могут использовать{% load static %}(вместо{% load staticfiles %}или{% load static from staticfiles %}) и не беспокоиться о том, установлено ли приложениеstaticfilesили нет.Вы можете более легко настроить опцию
collectstatic --ignoreс помощью специальногоAppConfig.
Кэш¶
Серверная часть файлового кэша теперь использует самый высокий протокол травления.
CSRF¶
Настройка по умолчанию: CSRF_FAILURE_VIEW, views.csrf.csrf_failure(), теперь принимает необязательный параметр template_name, по умолчанию равный 403_csrf.html, для управления шаблоном, используемым для визуализации страницы.
Для защиты от атак BREACH механизм защиты CSRF теперь меняет значение токена формы при каждом запросе (при этом сохраняя инвариантный секрет, который можно использовать для проверки различных токенов).
Серверные базы данных¶
Вычитание временных данных было унифицировано на всех серверах.
Если база данных поддерживает это, серверные части могут установить DatabaseFeatures.can_return_ids_from_bulk_insert=True и реализовать DatabaseOperations.fetch_returned_insert_ids() для установки первичных ключей для объектов, созданных с помощью QuerySet.bulk_create().
В методы as_sql() для различных выражений добавлены аргументы ключевых слов (Func, When, Case и OrderBy), позволяющие бэкэндам базы данных настраивать их без изменения self, что небезопасно при использовании разных бэкендов базы данных. Пример см. в параметрах
arg_joinerи**extra_contextFunc.as_sql().
Хранение файлов¶
Серверные части хранилища теперь представляют API с учетом часового пояса с новыми методами
get_accessed_time(),get_created_time()иget_modified_time(). Они возвращаютdatetimeс учетом часового пояса, еслиUSE_TZимеет значениеTrue, и наивноеdatetimeв локальном часовом поясе в противном случае.Новый метод
Storage.generate_filename()упрощает реализацию пользовательских хранилищ, которые не используют вызовыos.pathранее вFileField.
Формы¶
Форма и виджет «Медиа» теперь обслуживаются с использованием
django.contrib.staticfiles, если он установлен.Тег
<input>, отображаемый с помощьюCharField, теперь включает атрибутminlength, если поле имеетmin_length.Обязательные поля формы теперь имеют HTML-атрибут
required. Установите для нового атрибутаForm.use_required_attributeзначениеFalse, чтобы отключить его. Атрибутrequiredне включается в формы наборов форм, поскольку проверка браузера может быть неправильной при добавлении и удалении наборов форм.
Общие представления¶
Класс
Viewтеперь можно импортировать изdjango.views.
Интернационализация¶
Вспомогательную функцию
i18n_patterns()теперь можно использовать в корневом URLConf, указанном с помощьюrequest.urlconf.Установив для нового параметра
prefix_default_languageдляi18n_patterns()значениеFalse, вы можете разрешить доступ к языку по умолчанию без префикса URL.set_language()теперь возвращает код состояния 204 (нет содержимого) для запросов AJAX, когда вPOSTилиGETнет параметраnext.Представления на основе классов
JavaScriptCatalogиJSONCatalogзаменяют устаревшие представления на основе функцийjavascript_catalog()иjson_catalog(). Новые представления почти эквивалентны старым, за исключением того, что по умолчанию новые представления собирают все строки JavaScript в домене перевода djangojs из всех установленных приложений, а не только строки JavaScript изLOCALE_PATHS.
Команды управления¶
call_command()теперь возвращает значение, возвращенное методомcommand.handle().Новая опция
check --fail-levelпозволяет указать уровень сообщения, при котором команда завершится с ненулевым статусом.Новая опция
makemigrations --checkпозволяет завершить работу команды с ненулевым статусом при обнаружении изменений модели без миграции.makemigrationsтеперь отображает путь к файлам миграции, которые он генерирует.Опция
shell --interfaceтеперь принимаетpython, чтобы принудительно использовать «простой» интерпретатор Python.Новая опция
shell --commandпозволяет вам запустить команду от имени Django и выйти вместо открытия интерактивной оболочки.Добавлено предупреждение в
dumpdata, если указана модель прокси (что приводит к отсутствию вывода) без ее конкретного родителя.Новый атрибут
BaseCommand.requires_migrations_checksможет быть установлен вTrue, если вы хотите, чтобы ваша команда выводила предупреждение, как это делаетrunserver, если набор миграций на диске не соответствует миграциям в базе данных.Чтобы облегчить тестирование,
call_command()теперь принимает объект команды в качестве первого аргумента.Команда
shellподдерживает завершение табуляции в системах, использующихlibedit, например. macOS.Команда
inspectdbпозволяет вам выбрать, какие таблицы следует проверять, указав их имена в качестве аргументов.
Миграции¶
Добавлена поддержка сериализации объектов enum.Enum.
Добавлен аргумент
elidableв операцииRunSQLиRunPython, чтобы их можно было удалить при сжатии миграций.Добавлена поддержка неатомарных миграций путем установки атрибута
atomicдляMigration.Команды
migrateиmakemigrationsтеперь проверяют целостность истории миграции. Если они обнаруживают какие-то непримененные зависимости примененной миграции, возникает InconsistentMigrationHistory.Сигналы
pre_migrate()иpost_migrate()теперь отправляют своиplanиappsмиграции.
Модели¶
Обратные внешние ключи из прокси-моделей теперь распространяются на их конкретный класс. Обратное отношение, прикрепленное
ForeignKey, указывающее на прокси-модель, теперь доступно как дескриптор в прокси-классе модели, и на него можно ссылаться при фильтрации набора запросов.Новый метод
Field.rel_db_type()возвращает тип данных столбца базы данных для таких полей, какForeignKeyиOneToOneField, которые указывают на другое поле.Атрибут класса
arityдобавляется вFunc. Этот атрибут можно использовать для установки количества аргументов, которые принимает функция.Добавлен
BigAutoField, который действует очень похоже наAutoField, за исключением того, что он гарантированно помещает числа от1до9223372036854775807.QuerySet.in_bulk()может быть вызван без каких-либо аргументов для возврата всех объектов в наборе запросов.related_query_nameтеперь поддерживает интерполяцию меток приложения и классов с использованием строк'%(app_label)s'и'%(class)s'.Разрешено переопределение полей модели, унаследованных от абстрактных базовых классов.
Функция
prefetch_related_objects()теперь является общедоступным API.QuerySet.bulk_create()устанавливает первичный ключ для объектов при использовании PostgreSQL.Добавлена функция базы данных
Cast.Прокси-модель теперь может наследовать несколько прокси-моделей, которые имеют общий неабстрактный родительский класс.
Добавлены функции
Extractдля извлечения компонентов даты и времени в виде целых чисел, таких как год и час.Добавлены функции
Truncдля усечения даты или даты и времени до значимого компонента. Они позволяют запрашивать такие запросы, как продажи в день или продажи в час.Model.__init__()теперь устанавливает значения виртуальных полей из аргументов ключевого слова.Новые параметры
Meta.base_manager_nameиMeta.default_manager_nameпозволяют управлять_base_managerи_default_managerсоответственно.
Запросы и ответы¶
Добавлен
request.userв представление отладки.Добавлены методы
HttpResponsereadable()иseekable(), чтобы сделать экземпляр потокоподобным объектом и позволить обернуть его с помощьюio.TextIOWrapper.Добавлены атрибуты
HttpRequest.content_typeиcontent_params, которые анализируются из заголовкаCONTENT_TYPE.Анализатор request.COOKIES упрощен, чтобы лучше соответствовать поведению браузеров.
request.COOKIESтеперь может содержать файлы cookie, которые недействительны в соответствии с RFC 6265, но их можно установить черезdocument.cookie.
Сериализация¶
django.core.serializers.json.DjangoJSONEncoderтеперь знает, как сериализовать ленивые строки, обычно используемые для переводимого контента.
Шаблоны¶
Добавлена опция
autoescapeвDjangoTemplatesи в классEngine.В тег
ifдобавлены операторы сравненияisиis not.Разрешено
dictsortупорядочивать список списков по элементу по указанному индексу.Контекстный процессор
debug()содержит запросы для всех псевдонимов базы данных, а не только для псевдонима по умолчанию.Добавлена поддержка относительного пути для строковых аргументов тегов шаблона
extendsиinclude.
Тесты¶
Чтобы лучше выявлять ошибки,
TestCaseтеперь проверяет отложенные ограничения базы данных в конце каждого теста.Тесты и тестовые примеры можно помечать тегами и запускать выборочно с помощью новых опций
test --tagиtest --exclude-tag.Теперь вы можете входить в систему и использовать сеансы с тестовым клиентом, даже если
django.contrib.sessionsне находится вINSTALLED_APPS.
URL-адреса¶
Дополнение в
django.setup()позволяет разрешению URL-адресов, которое происходит вне цикла запрос/ответ (например, в командах управления и автономных скриптах), учитыватьFORCE_SCRIPT_NAME, когда он установлен.
Валидаторы¶
URLValidatorтеперь ограничивает длину меток доменных имен до 63 символов, а общую длину доменных имен до 253 символов на RFC 1034.int_list_validator()теперь принимает необязательный логический параметрallow_negative, по умолчанию равныйFalse, чтобы разрешить отрицательные целые числа.
Изменения обратной несовместимости в версии 1.10¶
Предупреждение
В дополнение к изменениям, изложенным в этом разделе, обязательно просмотрите Функции удалены в версии 1.10 для функций, срок устаревания которых достиг конца и поэтому был удален. Если вы не обновили свой код в течение срока прекращения поддержки определенной функции, ее удаление может выглядеть как обратно несовместимое изменение.
Серверный API базы данных¶
«AreaField» ГИС использует неопределенный базовый числовой тип, который на практике может быть любым числовым типом Python. Значения
decimal.Decimal, полученные из базы данных, теперь преобразуются вfloat, чтобы их было проще комбинировать со значениями, используемыми библиотеками ГИС.Чтобы включить временное вычитание, вы должны установить флаг функции базы данных support_temporal_subtraction в значение True и реализовать метод DatabaseOperations.subtract_temporals(). Этот метод должен возвращать SQL и параметры, необходимые для вычисления разницы в микросекундах между аргументами
lhsиrhsв типе данных, используемом для храненияDurationField.
_meta.get_fields() возвращает согласованные обратные поля для прокси-моделей.¶
До Django 1.10 метод get_fields() возвращал разные обратные поля при вызове прокси-модели по сравнению с ее прокси-конкретным классом. Это несоответствие было исправлено путем возврата полного набора полей, указывающих на конкретный класс или один из его прокси в обоих случаях.
AbstractUser.username max_length увеличено до 150¶
Включена миграция для django.contrib.auth.models.User.username. Если у вас есть пользовательская модель, унаследованная от «AbstractUser», вам необходимо сгенерировать и применить миграцию базы данных для вашей пользовательской модели.
Мы рассматривали возможность увеличения длины до 254 символов, чтобы упростить использование адресов электронной почты (длина которых ограничена 254 символами) в качестве имен пользователей, но отклонили эту идею из-за ограничений MySQL. При использовании кодировки utf8mb4 (рекомендуется для правильной поддержки Unicode) MySQL по умолчанию может создавать только уникальные индексы длиной 191 символ. Поэтому, если вам нужна более длинная длина, используйте собственную модель пользователя.
Если вы хотите сохранить ограничение в 30 символов для имен пользователей, используйте специальную форму при создании пользователя или изменении имен пользователей:
from django.contrib.auth.forms import UserCreationForm
class MyUserCreationForm(UserCreationForm):
username = forms.CharField(
max_length=30,
help_text="Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.",
)
Если вы хотите сохранить это ограничение в администраторе, установите UserAdmin.add_form для использования этой формы:
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
class UserAdmin(BaseUserAdmin):
add_form = MyUserCreationForm
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Прекращена поддержка PostgreSQL 9.1.¶
Поддержка исходной версии PostgreSQL 9.1 заканчивается в сентябре 2016 года. Как следствие, Django 1.10 устанавливает PostgreSQL 9.2 как минимальную официально поддерживаемую версию.
Вывод runserver проходит протоколирование¶
Обработка запросов и ответов на команду runserver отправляется в регистратор django-server-logger вместо sys.stderr. Если вы отключите конфигурацию ведения журнала Django или замените ее своей собственной, вам нужно будет добавить соответствующую конфигурацию ведения журнала, если вы хотите видеть этот вывод:
LOGGING = {
# ...
"formatters": {
"django.server": {
"()": "django.utils.log.ServerFormatter",
"format": "[%(server_time)s] %(message)s",
}
},
"handlers": {
"django.server": {
"level": "INFO",
"class": "logging.StreamHandler",
"formatter": "django.server",
},
},
"loggers": {
"django.server": {
"handlers": ["django.server"],
"level": "INFO",
"propagate": False,
}
},
}
Тестовые модели auth.CustomUser и auth.ExtensionUser были удалены.¶
С момента появления миграций для дополнительных приложений в Django 1.8 таблицы этих пользовательских тестовых моделей больше не создавались, что делало их непригодными для использования в контексте тестирования.
Реестр приложений больше не заполняется автоматически при распаковке моделей за пределами Django.¶
Реестр приложений больше не заполняется автоматически при разборе моделей. Это было добавлено в Django 1.7.2 как попытка разрешить распаковку моделей за пределами Django, например, в RQ-воркере, без вызова django.setup(), но это создает возможность взаимоблокировки. Чтобы адаптировать свой код для RQ, вы можете предоставить свой собственный рабочий скрипт <https://python-rq.org/docs/workers/>`_, который вызывает ``django.setup().
Удалена проверка присвоения значения NULL для полей внешнего ключа, отличных от NULL.¶
В более старых версиях присвоение None необнуляемому элементу ForeignKey или OneToOneField вызывало ошибку ValueError(„Невозможно назначить None: «model.field» не допускает нулевых значений.“)``. Для согласованности с другими полями модели, у которых нет аналогичной проверки, эта проверка удалена.
Удалены слабые хешеры паролей из настройки PASSWORD_HASHERS по умолчанию.¶
Django 0.90 хранил пароли в виде несоленого MD5. В Django 0.91 добавлена поддержка соленого SHA1 с автоматическим обновлением паролей при входе пользователя в систему. В Django 1.4 добавлен PBKDF2 в качестве хэшера паролей по умолчанию.
Если у вас есть старый проект Django с паролями, закодированными в формате MD5 или SHA1 (даже солеными), имейте в виду, что их можно довольно легко взломать с помощью современного оборудования. Чтобы пользователи Django признавали дальнейшее использование слабых хешеров, из настройки по умолчанию PASSWORD_HASHERS удалены следующие хешеры:
"django.contrib.auth.hashers.SHA1PasswordHasher""django.contrib.auth.hashers.MD5PasswordHasher""django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher""django.contrib.auth.hashers.UnsaltedMD5PasswordHasher""django.contrib.auth.hashers.CryptPasswordHasher"
Рассмотрите возможность использования обернутого хэшера паролей для усиления хешей в вашей базе данных. Если это невозможно, добавьте параметр PASSWORD_HASHERS в свой проект и добавьте обратно все необходимые хешеры.
Вы можете проверить, есть ли в вашей базе данных какие-либо удаленные хэши, например:
from django.contrib.auth import get_user_model
User = get_user_model()
# Unsalted MD5/SHA1:
User.objects.filter(password__startswith="md5$$")
User.objects.filter(password__startswith="sha1$$")
# Salted MD5/SHA1:
User.objects.filter(password__startswith="md5$").exclude(password__startswith="md5$$")
User.objects.filter(password__startswith="sha1$").exclude(password__startswith="sha1$$")
# Crypt hasher:
User.objects.filter(password__startswith="crypt$$")
from django.db.models import CharField
from django.db.models.functions import Length
CharField.register_lookup(Length)
# Unsalted MD5 passwords might not have an 'md5$$' prefix:
User.objects.filter(password__length=32)
Методы Field.get_prep_lookup() и Field.get_db_prep_lookup() удалены.¶
Если у вас есть настраиваемое поле, реализующее любой из этих методов, зарегистрируйте для него настраиваемый поиск. Например:
from django.db.models import Field
from django.db.models.lookups import Exact
class MyField(Field): ...
class MyFieldExact(Exact):
def get_prep_lookup(self):
# do_custom_stuff_for_myfield
...
MyField.register_lookup(MyFieldExact)
django.contrib.gis¶
Поддержка SpatiaLite < 3.0 и GEOS < 3.3 прекращена.
Псевдоним обратной совместимости add_postgis_srs() для django.contrib.gis.utils.add_srs_entry() удален.
В Oracle/GIS агрегатная функция
Areaтеперь возвращает значениеfloatвместоdecimal.Decimal. (Он все еще завернут в квадратные метры.)Представление
GEOSGeometryпо умолчанию (выходные данные WKT) обрезается по умолчанию. То есть вместоPOINT (23.0000000000000000 5.5000000000000000)вы получитеPOINT (23 5.5).
Максимальный размер тела запроса и количество параметров GET/POST ограничены.¶
Две новые настройки помогают смягчить атаки типа «отказ в обслуживании» посредством больших запросов:
DATA_UPLOAD_MAX_MEMORY_SIZEограничивает размер тела запроса. Загрузка файлов не учитывается в этом лимите.DATA_UPLOAD_MAX_NUMBER_FIELDSограничивает количество анализируемых параметров GET/POST.
Приложениям, которые получают сообщения необычно большой формы, возможно, потребуется настроить эти параметры.
Разнообразный¶
repr()изQuerySetзаключен в<QuerySet >, чтобы исключить неоднозначность его из простого списка при отладке.utils.version.get_version()возвращает версии-кандидаты на выпуск, соответствующие PEP 440 (например, „1.10rc1“ вместо „1.10c1“).Значения токена CSRF теперь должны быть строками из 64 букв и цифр; значения из 32 букв и цифр, установленные по умолчанию в старых версиях Django, автоматически заменяются строками из 64 символов. Остальные значения считаются недействительными. Это должно коснуться только разработчиков или пользователей, которые заменяют эти токены.
Параметр
LOGOUT_URLудален, поскольку Django не использовал его с версии до версии 1.0. Если вы используете его в своем проекте, вы можете добавить его в настройки вашего проекта. Значением по умолчанию было'/accounts/logout/'.Объекты с методом close(), такие как файлы и генераторы, переданные в
HttpResponse, теперь закрываются немедленно, а не тогда, когда сервер WSGI вызывает close() в ответе.Избыточный вызов transaction.atomic() в QuerySet.update_or_create() удален. Это может повлиять на количество запросов, проверенных с помощью TransactionTestCase.assertNumQueries().
Поддержка Skip_validation в BaseCommand.execute(**options) удалена. Вместо этого используйте Skip_checks (добавлен в Django 1.7).
loaddataтеперь вызываетCommandErrorвместо отображения предупреждения, когда указанный файл фикстуры не найден.Вместо прямого доступа к атрибуту LogEntry.change_message теперь лучше вызвать метод LogEntry.get_change_message(), который предоставит сообщение на текущем языке.
Представления ошибок по умолчанию теперь вызывают «TemplateDoesNotExist», если указано несуществующее «template_name».
Неиспользуемый аргумент ключевого слова «choices» метода «render()» виджетов «Select» и «SelectMultiple» удален. Аргумент
choicesметодаrender_options()также удаляется, делаяselected_choicesпервым аргументом.Тесты, нарушающие отложенные ограничения базы данных, теперь будут вызывать ошибку при запуске в базе данных, поддерживающей отложенные ограничения.
Встроенные команды управления теперь используют индексацию ключей в
options, например.options['verbosity']вместоoptions.get()и больше не выполняет никакого приведения типов. Это может быть проблемой, если вы вызываете команды, используяCommand.execute()(который обходит анализатор аргументов, который устанавливает значение по умолчанию) вместоcall_command(). Вместо вызова Command.execute() передайте объект команды в качестве первого аргумента в call_command().ModelBackendиRemoteUserBackendтеперь отклоняют неактивных пользователей. Это означает, что неактивные пользователи не могут войти в систему и будут отключены, если они переключятся сis_active=TrueнаFalse. Если вам нужно предыдущее поведение, используйте вместо этого новыйAllowAllUsersModelBackendилиAllowAllUsersRemoteUserBackendвAUTHENTICATION_BACKENDS.В свете предыдущего изменения метод
login()тестового клиента больше не всегда отклоняет неактивных пользователей, а вместо этого делегирует это решение серверной части аутентификации.force_login()также делегирует принятие решения серверу аутентификации, поэтому, если вы используете серверы по умолчанию, вам необходимо использовать активного пользователя.django.views.i18n.set_language()теперь может возвращать код состояния 204 для запросов AJAX.Атрибут
base_fieldRangeFieldтеперь является типом поля, а не экземпляром поля. Если вы создали собственный подклассRangeField, вам следует изменить атрибутbase_field.Классы промежуточного программного обеспечения теперь инициализируются при запуске сервера, а не во время первого запроса.
Если вы переопределяете
is_authenticated()илиis_anonymous()в пользовательской модели пользователя, вы должны преобразовать их в атрибуты или свойства, как описано в примечании об устаревании.При использовании
ModelAdmin.save_as=Trueкнопка «Сохранить как новый» теперь перенаправляет к представлению изменений для нового объекта, а не к списку изменений модели. Если вам нужно предыдущее поведение, установите для нового атрибутаModelAdmin.save_as_continueзначениеFalse.Обязательные поля формы теперь имеют HTML-атрибут
required. Установите для атрибутаForm.use_required_attributeзначениеFalse, чтобы отключить его. Вы также можете добавить атрибутnovalidateв<form>, если вам не нужна проверка браузера. Чтобы отключить атрибутrequiredв пользовательских виджетах, переопределите методWidget.use_required_attribute().Обработчик WSGI больше не удаляет содержимое ответов из запросов HEAD или ответов с кодом статуса 100–199, 204 или 304. Большинство веб-серверов уже реализуют такое поведение. К ответам, полученным с помощью тестового клиента Django, по-прежнему применяются эти «исправления ответов».
Model.__init__()теперь получаетdjango.db.models.DEFERREDв качестве значения отложенных полей.Атрибут Model._deferred удаляется как классы динамической модели при использовании QuerySet.defer() и only().
Storage.save()больше не заменяет'\'на'/'. Это поведение перенесено вFileSystemStorage, поскольку это деталь реализации, специфичная для хранилища. Любой пользователь Windows с собственной реализацией хранилища, использующей это поведение, должен будет реализовать его в методеsave()пользовательского хранилища.Частные
FileFieldметодыget_directory_name()иget_filename()больше не вызываются (и теперь считаются устаревшими), что является изменением обратной несовместимости для пользователей, переопределяющих эти методы в настраиваемых полях. Чтобы адаптировать такой код, вместо этого переопределите FileField.generate_filename() илиStorage.generate_filename(). Возможно, также можно использоватьupload_to.Тема письма, отправляемого AdminEmailHandler, больше не обрезается до 989 символов. Если вы рассчитывали на ограниченную длину, сократите тему самостоятельно.
Частные выражения
django.db.models.expressions.DateиDateTimeудалены. Новые выраженияTruncпредоставляют ту же функциональность.Атрибуты _base_manager и _default_manager удалены из экземпляров модели. Они остаются доступными в классе модели.
Доступ к удаленному полю в экземпляре модели, например. после del obj.field перезагружает значение поля вместо вызова AttributeError.
Если вы создадите подкласс AbstractBaseUser и переопределите clean(), убедитесь, что он вызывает super().
AbstractBaseUser.normalize_username()вызывается в новом методеAbstractBaseUser.clean().Частный API
django.forms.models.model_to_dict()возвращает набор запросов, а не список первичных ключей дляManyToManyFields.Если установлен
django.contrib.staticfiles, тег шаблонаstaticиспользует хранилищеstaticfilesдля создания URL-адреса, а не просто объединяет значение сSTATIC_ROOT. Новый подход кодирует URL-адрес, который может быть обратно несовместим в таких случаях, как включение фрагмента в путь, например{% static 'img.svg#fragment' %}, поскольку#закодирован как%23. Чтобы адаптироваться, переместите фрагмент за пределы тега шаблона:{% static 'img.svg' %}#fragment.Когда
USE_L10Nимеет значениеTrue, локализация теперь применяется для фильтровdateиtime, когда не указана строка формата. Спецификаторы DATE_FORMAT и TIME_FORMAT из активной локали используются вместо одноименных настроек.
Функции, устаревшие в версии 1.10¶
Прямое присвоение обратному внешнему ключу или отношению «многие ко многим».¶
Вместо назначения связанных объектов с помощью прямого присвоения:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
Используйте метод set(), добавленный в Django 1.9:
>>> e.related_set.set([obj1, obj2, obj3])
Это предотвращает путаницу в назначении, приводящую к неявному сохранению.
Storage API без учета часового пояса¶
Старые, не учитывающие часовой пояс методы accessed_time(), create_time() и modified_time() устарели в пользу новых методов get_*_time().
Сторонние серверные системы хранения должны реализовать новые методы и пометить старые как устаревшие. До тех пор новые методы get_*_time() в базовом классе Storage преобразуют datetimes из старых методов по мере необходимости и при этом выдают предупреждение об устаревании.
Сторонние серверные системы хранения могут сохранять старые методы, если они хотят поддерживать более ранние версии Django.
django.contrib.gis¶
Методы
get_srid()иset_srid()GEOSGeometryустарели в пользу свойстваsrid.Методы
get_x(),set_x(),get_y(),set_y(),get_z()иset_z()Pointустарели в пользу свойствx,yиz.Методы
get_coords()иset_coords()Pointустарели в пользу свойстваtuple.Свойство
cascaded_unionMultiPolygonустарело в пользу свойстваunary_union.Функция
django.contrib.gis.utils.precision_wkt()устарела в пользуWKTWriter.
Поле модели CommaSeparatedIntegerField¶
CommaSeparatedIntegerField устарел в пользу CharField с валидатором validate_comma_separated_integer_list():
from django.core.validators import validate_comma_separated_integer_list
from django.db import models
class MyModel(models.Model):
numbers = models.CharField(..., validators=[validate_comma_separated_integer_list])
Если вы используете Oracle, CharField использует другой тип поля базы данных (NVARCHAR2), чем CommaSeparatedIntegerField (VARCHAR2). В зависимости от настроек вашей базы данных это может означать разную кодировку и, следовательно, разную длину (в байтах) для одного и того же содержимого. Если ваши сохраненные значения длиннее, чем предел NVARCHAR2 в 4000 байт, вместо этого вам следует использовать TextField (NCLOB). В этом случае, если у вас есть какие-либо запросы, которые группируются по полю (например, аннотирование модели с помощью агрегирования или использование distinct()), вам нужно будет изменить их (чтобы отложить поле).
__search поиск по запросу¶
Поиск search, который поддерживает только MySQL и имеет крайне ограниченные возможности, устарел. Замените его пользовательским поиском:
from django.db import models
class Search(models.Lookup):
lookup_name = "search"
def as_mysql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return "MATCH (%s) AGAINST (%s IN BOOLEAN MODE)" % (lhs, rhs), params
models.CharField.register_lookup(Search)
models.TextField.register_lookup(Search)
Использование User.is_authenticated() и User.is_anonymous() в качестве методов.¶
Методы is_authenticated() и is_anonymous() классов AbstractBaseUser и AnonymousUser теперь являются свойствами. Они по-прежнему будут работать как методы до Django 2.0, но теперь для всего использования в Django используется доступ к атрибутам.
Например, если вы используете AuthenticationMiddleware и хотите узнать, вошел ли пользователь в систему в данный момент, вы должны использовать:
if request.user.is_authenticated:
... # Do something for logged-in users.
else:
... # Do something for anonymous users.
вместо request.user.is_authenticated().
Это изменение позволяет избежать случайной утечки информации, если вы забудете вызвать метод, например:
if request.user.is_authenticated:
return sensitive_information
Если вы переопределяете эти методы в пользовательской модели пользователя, вам необходимо изменить их на свойства или атрибуты.
Django использует объект CallableBool, чтобы позволить этим атрибутам работать и как свойство, и как метод. Таким образом, пока не закончится период устаревания, вы не сможете сравнивать эти свойства с помощью оператора is. То есть следующее не будет работать:
if request.user.is_authenticated is True:
...
«Эскейп-половина» django.utils.safestring``¶
Функция mark_for_escaping() и используемые ею классы: EscapeData, EscapeBytes, EscapeText, EscapeString и EscapeUnicode считаются устаревшими.
В результате «ленивое» поведение фильтра escape (когда он всегда применялся как последний фильтр, независимо от того, где в цепочке фильтров он появлялся) считается устаревшим. Фильтр изменится и немедленно применит conditional_escape() в Django 2.0.
Разнообразный¶
Опция makemigrations –exit устарела в пользу опции
makemigrations --check.django.utils.functional.allow_lazy()устарел в пользу новой функцииkeep_lazy(), которую можно использовать с более естественным синтаксисом декоратора.Опция
shell --plainустарела в пользу-i pythonили--interface python.Импорт из модуля
django.core.urlresolversустарел в пользу его нового местоположения,django.urls.Шаблонный метод Context.has_key() устарел в пользу метода in.
Частный атрибут
virtual_fieldsвModel._metaустарел в пользуprivate_fields.Аргументы частного ключевого слова
virtual_onlyвField.contribute_to_class()иvirtualвModel._meta.add_field()устарели в пользуprivate_onlyиprivateсоответственно.Представления
javascript_catalog()иjson_catalog()устарели в пользу представлений на основе классовJavaScriptCatalogиJSONCatalog.При многотабличном наследовании неявное повышение OneToOneField до родительской ссылки считается устаревшим. Добавьте в такие поля
parent_link=True.Частный API Widget._format_value() стал общедоступным и переименован в
format_value(). Старое имя будет действовать в течение периода устаревания.Частные методы FileField
get_directory_name()иget_filename()устарели в пользу выполнения этой работы вStorage.generate_filename()).Промежуточное программное обеспечение старого типа, использующее
settings.MIDDLEWARE_CLASSES, считается устаревшим. Адаптируйте старое пользовательское промежуточное ПО и используйте новый параметрMIDDLEWARE.
Функции удалены в версии 1.10¶
Эти функции достигли конца цикла устаревания и удалены в Django 1.10. См. Функции, устаревшие в версии 1.8 для получения подробной информации, в том числе о том, как прекратить использование этих функций.
Поддержка вызова SQLCompiler напрямую в качестве псевдонима для вызова его метода quote_name_unless_alias удалена.
Теги шаблонов
cycleиfirstofудалены из библиотеки тегов шаблоновfuture.django.conf.urls.patterns()удален.Поддержка аргумента
prefixдляdjango.conf.urls.i18n.i18n_patterns()удалена.SimpleTestCase.urlsудален.Использование неправильного количества распакованных значений в теге шаблона for вызывает исключение, а не сбой без уведомления.
Удалена возможность
reverse()URL-адресов с использованием точечного пути Python.Возможность использовать пунктирный путь Python для настроек LOGIN_URL и LOGIN_REDIRECT_URL удалена.
Поддержка optparse прекращена для пользовательских команд управления.
Класс django.core.management.NoArgsCommand удален.
Модуль
django.core.context_processorsудален.Модуль
django.db.models.sql.aggregatesудален.Модуль
django.contrib.gis.db.models.sql.aggregatesудален.Следующие методы и свойства django.db.sql.query.Query удалены:
Свойства:
агрегатыиaggregate_selectМетоды: add_aggregate, set_aggregate_mask иappend_aggregate_mask.
django.template.resolve_variableудален.Следующие частные API удалены из
django.db.models.options.Options(Model._meta):get_field_by_name()get_all_field_names()get_fields_with_model()get_concrete_fields_with_model()get_m2m_with_model()get_all_related_objects()get_all_related_objects_with_model()get_all_lated_many_to_many_objects()get_all_lated_m2m_objects_with_model()
Аргумент error_message файла django.forms.RegexField удален.
Фильтр unordered_list больше не поддерживает списки старого стиля.
Поддержка строковых аргументов
viewдляurl()удалена.Обратная совместимая оболочка для переименования
django.forms.Form._has_changed()вhas_changed()удалена.Фильтр шаблона
removetagsудален.Функции
remove_tags()иstrip_entities()вdjango.utils.htmlудалены.Аргумент is_admin_site для django.contrib.auth.views.password_reset() удален.
django.db.models.field.subclassing.SubfieldBaseудален.django.utils.checksumsудален.Атрибут original_content_type_id в django.contrib.admin.helpers.InlineAdminForm удален.
Оболочка обратной совместимости, позволяющая определять FormMixin.get_form() без значения по умолчанию для аргумента form_class, удалена.
Следующие настройки будут удалены, и вам необходимо обновить настройку до настройки
TEMPLATES:ALLOWED_INCLUDE_ROOTSTEMPLATE_CONTEXT_PROCESSORSTEMPLATE_DEBUGTEMPLATE_DIRSTEMPLATE_LOADERSTEMPLATE_STRING_IF_INVALID
Псевдоним обратной совместимости
django.template.loader.BaseLoaderудален.Объекты шаблона Django, возвращаемые
get_template()иselect_template(), больше не принимаютContextв своем методеrender().API ответа шаблона обеспечивают использование
dictи объектов шаблонов, зависящих от серверной части, вместоContextиTemplateсоответственно.Параметр current_app для следующей функции и классов удален:
django.shortcuts.render()django.template.Context()django.template.RequestContext()django.template.response.TemplateResponse()
Параметры
dictionaryиcontext_instanceдля следующих функций удалены:django.shortcuts.render()django.shortcuts.render_to_response()django.template.loader.render_to_string()
Параметр
dirsдля следующих функций удален:django.template.loader.get_template()django.template.loader.select_template()django.shortcuts.render()django.shortcuts.render_to_response()
Проверка сеанса включена независимо от того, находится ли
'django.contrib.auth.middleware.SessionAuthenticationMiddleware'вMIDDLEWARE_CLASSES.SessionAuthenticationMiddlewareбольше не имеет никакого назначения и может быть удален изMIDDLEWARE_CLASSES. До Django 2.0 он хранится как заглушка для удобства пользователей, которые не читают эту заметку.Частный атрибут django.db.models.Field.related удален.
Опция
--listкоманды управленияmigrateудалена.Тег шаблона
ssiудален.Поддержка оператора сравнения
=в теге шаблонаifудалена.Прокладки обратной совместимости, позволяющие определять
Storage.get_available_name()иStorage.save()без аргументаmax_length, удалены.Поддержка устаревшего синтаксиса %(<foo>)s в ModelFormMixin.success_url удалена.
Агрегатные методы
GeoQuerySet``collect(),extent(),extent3d(),make_line()иunionagg()удалены.Возможность указать «ContentType.name» при создании экземпляра типа контента удалена.
Поддержка старой подписи
allow_migrateудалена.Удалена поддержка синтаксиса
{% Cycle %}, который использует аргументы, разделенные запятыми.Предупреждение, которое
Signerвыдает при указании недопустимого разделителя, теперь являетсяValueError.