Примечания к выпуску Django 1.10¶
1 августа 2016
Добро пожаловать в Django 1.10!
Эти заметки о выпуске охватывают new features, а также некоторые backwards incompatible changes, о которых вы должны знать при переходе с Django 1.9 или более старых версий. Мы dropped some features, которые достигли конца своего цикла обесценивания, и мы begun the deprecation process for some features.
См. руководство Как обновить Django до более новой версии, если вы обновляете существующий проект.
Совместимость с Python¶
Как и Django 1.9, Django 1.10 требует Python 2.7, 3.4 или 3.5. Мы настоятельно рекомендуем и официально поддерживаем только последний выпуск каждой серии.
Что нового в Django 1.10¶
Полнотекстовый поиск для PostgreSQL¶
django.contrib.postgres теперь включает collection of database functions, позволяющий использовать полнотекстовую поисковую систему. Вы можете искать по нескольким полям реляционной базы данных, комбинировать поиск с другими поисками, использовать различные языковые конфигурации и весовые коэффициенты, а также ранжировать результаты по релевантности.
Кроме того, теперь он поддерживает триграммы, используя поиск trigram_similar и выражения TrigramSimilarity и TrigramDistance.
Промежуточное программное обеспечение нового типа¶
A new style of middleware is introduced для решения проблемы отсутствия строгого наслоения запросов/ответов в старом стиле промежуточного программного обеспечения, описанного в DEP 0005. Вам нужно будет adapt old, custom middleware и переключиться с настройки MIDDLEWARE_CLASSES на новую настройку MIDDLEWARE, чтобы воспользоваться преимуществами улучшений.
Официальная поддержка имен пользователей Unicode¶
Модель User в django.contrib.auth изначально принимала в именах пользователей только буквы и цифры ASCII. Хотя это не было преднамеренным выбором, символы Unicode всегда принимались при использовании Python 3.
Валидатор имени пользователя теперь явно принимает символы Unicode по умолчанию только в Python 3.
Пользовательские модели могут использовать новые ASCIIUsernameValidator или UnicodeUsernameValidator.
Незначительные особенности¶
django.contrib.admin¶
- Для сайтов, работающих на подпути, стандартный
URL for the "View site" linkв верхней части каждой страницы администратора теперь будет указывать на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, если поле является нулевым. - Библиотека jQuery, встроенная в админку, обновлена с версии 2.1.4 до 2.2.3.
django.contrib.auth¶
- Добавлена поддержка Argon2 password hash. Она рекомендуется вместо PBKDF2, однако не используется по умолчанию, так как требует использования сторонней библиотеки.
- Количество итераций по умолчанию для хешера паролей PBKDF2 было увеличено на 25%. Это обратно совместимое изменение не повлияет на пользователей, которые подклассифицировали
django.contrib.auth.hashers.PBKDF2PasswordHasherдля изменения значения по умолчанию. - Представление
django.contrib.auth.views.logout()отправляет заголовки «no-cache» для предотвращения проблемы, когда Safari кэширует перенаправления и не позволяет пользователю выйти из системы. - Добавлен необязательный аргумент
backendвdjango.contrib.auth.login(), позволяющий использовать его без учетных данных. - Новая настройка
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¶
- Distance lookups теперь принимают выражения в качестве параметра значения расстояния.
- Новое свойство
GEOSGeometry.unary_unionвычисляет объединение всех элементов этой геометрии. - Добавлен бинарный предикат
GEOSGeometry.covers(). - Добавлены метод
GDALBand.statistics()и атрибутыmeanиstd. - Добавлена поддержка агрегата
MakeLineи функцииGeoHashна SpatiaLite. - Добавлена поддержка функций
Difference,IntersectionиSymDifferenceв MySQL. - Добавлена поддержка инстанцирования пустых геометрий GEOS.
- Новые свойства
trimиprecisionвWKTWriterпозволяют управлять выводом дробной части координат в WKT. - Добавлены свойства
LineString.closedиMultiLineString.closed. - GeoJSON serializer теперь выводит первичный ключ объектов в словаре
properties, если не указаны конкретные поля. - Добавлена возможность повторения входных данных по методу
GDALBand.data(). Теперь данные диапазона можно эффективно обновлять с помощью повторяющихся значений. - Добавлены функции базы данных
IsValidиMakeValid, а также поискisvalid, все для PostGIS. Это позволяет фильтровать и исправлять недействительные геометрии на стороне базы данных. - Добавлена поддержка растра для всех spatial lookups.
django.contrib.postgres¶
- Для удобства
HStoreFieldтеперь приводит свои ключи и значения к строкам.
django.contrib.sessions¶
- Команда управления
clearsessionsтеперь удаляет сессии на основе файлов.
django.contrib.sites¶
- Модель
Siteтеперь поддерживает natural keys.
django.contrib.staticfiles¶
- Тег шаблона
staticтеперь используетdjango.contrib.staticfiles, если он находится вINSTALLED_APPS. Это особенно полезно для сторонних приложений, которые теперь всегда могут использовать{% load static %}(вместо{% load staticfiles %}или{% load static from staticfiles %}) и не беспокоиться о том, установлено ли приложениеstaticfiles. - Вы можете more easily customize использовать опцию
collectstatic --ignoreс пользовательскойAppConfig.
Кэш¶
- Бэкэнд кэша на основе файлов теперь использует самый высокий протокол pickling.
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_contextвFunc.as_sql().
Хранение файлов¶
- Бэкенды хранилищ теперь представляют API с учетом временной зоны с новыми методами
get_accessed_time(),get_created_time()иget_modified_time(). Они возвращают значениеdatetime, еслиUSE_TZявляетсяTrue, и наивное значениеdatetimeв местном часовом поясе в противном случае. - Новый метод
Storage.generate_filename()облегчает реализацию пользовательских хранилищ, которые не используют вызовыos.path, которые ранее были вFileField.
Формы¶
- Форма и виджет
Mediaтеперь обслуживаются с использованиемdjango.contrib.staticfiles, если они установлены. - Тег
<input>, отображаемыйCharField, теперь включает атрибутminlength, если поле имеетmin_length. - Обязательные поля формы теперь имеют HTML-атрибут
required. Установите новый атрибутForm.use_required_attributeнаFalse, чтобы отключить его. Атрибутrequiredне включен в формы наборов форм, потому что валидация браузера может быть некорректной при добавлении и удалении наборов форм.
Интернационализация¶
- Вспомогательная функция
i18n_patterns()теперь может быть использована в корневой URLConf, заданной с помощьюrequest.urlconf. - Установив новый параметр
prefix_default_languageдляi18n_patterns()в значениеFalse, вы можете разрешить доступ к языку по умолчанию без префикса URL. set_language()теперь возвращает код состояния 204 (No Content) для запросов AJAX, когда вnextилиPOSTотсутствует параметрGET.- Представления на основе классов
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, чтобы их можно было удалить при сминании миграций. - Добавлена поддержка non-atomic migrations путем установки атрибута
atomicнаMigration. - Команды
migrateиmakemigrationsтеперь check for a consistent migration history. Если они находят некоторые непримененные зависимости примененной миграции, то выдается сообщение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теперь может содержать куки, которые недопустимы согласно RFC 6265, но могут быть установлены черезdocument.cookie.
Сериализация¶
django.core.serializers.json.DjangoJSONEncoderтеперь знает, как сериализовать ленивые строки, обычно используемые для переводимого содержимого.
Шаблоны¶
- Добавлена опция
autoescapeк бэкендуDjangoTemplatesи классуEngine. - Добавлены операторы сравнения
isиis notк тегуif. - Позволяет
dictsortупорядочить список списков по элементу с указанным индексом. - Контекстный процессор
debug()содержит запросы для всех псевдонимов базы данных, а не только для псевдонима по умолчанию. - Добавлена поддержка относительных путей для строковых аргументов тегов шаблонов
extendsиinclude.
Тесты¶
- Чтобы лучше отлавливать ошибки,
TestCaseтеперь проверяет откладываемые ограничения базы данных в конце каждого теста. - Тесты и тестовые случаи могут быть marked with tags и запускаться выборочно с помощью новых опций
test --tagиtest --exclude-tag. - Теперь вы можете входить и использовать сессии с тестовым клиентом, даже если
django.contrib.sessionsне находится вINSTALLED_APPS.
URLs¶
- Добавление в
django.setup()позволяет разрешению URL, происходящему вне цикла запрос/ответ (например, в командах управления и автономных скриптах), учитыватьFORCE_SCRIPT_NAMEпри его установке.
Валидаторы¶
URLValidatorтеперь ограничивает длину меток доменных имен до 63 символов, а общую длину доменных имен до 253 символов на RFC 1034.int_list_validator()теперь принимает необязательный булев параметрallow_negative, по умолчаниюFalse, чтобы разрешить отрицательные целые числа.
Изменения в 1.10, несовместимые с обратными изменениями¶
Предупреждение
В дополнение к изменениям, описанным в этом разделе, обязательно просмотрите Функции, удаленные в версии 1.10 для функций, которые достигли конца своего цикла устаревания и поэтому были удалены. Если вы не обновили свой код в течение срока устаревания данной функции, ее удаление может выглядеть как изменение, несовместимое с обратным ходом развития.
API бэкенда базы данных¶
- В
AreaFieldв GIS используется неопределенный базовый числовой тип, который на практике может быть любым числовым типом Python. Значенияdecimal.Decimal, получаемые из базы данных, теперь преобразуются вfloat, чтобы их было проще объединить со значениями, используемыми библиотеками GIS. - Чтобы включить временное вычитание, необходимо установить флаг функции базы данных
supports_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, а не в sys.stderr. Если вы отключите конфигурацию логирования Django или переопределите ее своей собственной, вам нужно будет добавить соответствующую конфигурацию логирования, если вы хотите видеть этот вывод:
'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 были удалены¶
После введения миграций для приложений contrib в Django 1.8, таблицы этих пользовательских тестовых моделей больше не создавались, что делает их непригодными для использования в контексте тестирования.
Реестр приложений больше не заполняется автоматически при распаковке моделей вне Django¶
Реестр приложений больше не заполняется автоматически при распаковке моделей. Это было добавлено в Django 1.7.2 как попытка позволить распаковывать модели вне Django, например, в RQ worker, без вызова django.setup(), но это создает возможность тупика. Чтобы адаптировать ваш код в случае RQ, вы можете provide your own worker script, который вызывает django.setup().
Устранена проверка присвоения нуля для ненулевых полей внешнего ключа¶
В старых версиях присвоение None ненулевому ForeignKey или OneToOneField приводило к появлению ValueError('Cannot assign None: "model.field" does not allow null values.'). Для согласованности с другими полями модели, не имеющими подобной проверки, эта проверка удалена.
Удалены слабые хешеры паролей из настройки по умолчанию 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'
Рассмотрите возможность использования wrapped password hasher для усиления хэшей в вашей базе данных. Если это невозможно, добавьте параметр 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в методеSelectиSelectMultipleвиджетовrender()удален. Аргумент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_fieldвRangeFieldтеперь является типом поля, а не экземпляром поля. Если вы создали пользовательский подклассRangeField, вам следует изменить атрибутbase_field. - Классы Middleware теперь инициализируются при запуске сервера, а не во время первого запроса.
- Если вы переопределяете
is_authenticated()илиis_anonymous()в пользовательской модели пользователя, вы должны преобразовать их в атрибуты или свойства, как описано в the deprecation note. - При использовании
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или ответы сstatus_codeна 100-199, 204 или 304. Большинство веб-серверов уже реализуют такое поведение. Ответы, полученные с помощью тестового клиента Django, продолжают иметь эти «исправления ответа». Model.__init__()теперь получаетdjango.db.models.DEFERREDв качестве значения отложенных полей.- Атрибут
Model._deferredудаляется в качестве классов динамической модели при использованииQuerySet.defer()иonly()удаляется. Storage.save()больше не заменяет'\'на'/'. Это поведение перенесено вFileSystemStorage, поскольку это деталь реализации, специфичная для конкретного хранилища. Любой пользователь Windows с пользовательской реализацией хранилища, которая полагается на это поведение, должен будет реализовать его в методеsave()пользовательского хранилища.- Приватные методы
FileFieldget_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])
Это предотвращает путаницу, когда присваивание приводит к неявному сохранению.
API без учета временных зон Storage¶
Старые методы accessed_time(), created_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_unionдляMultiPolygonустарело в пользу свойства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). В зависимости от настроек вашей базы данных, это может означать разную кодировку и, следовательно, разную длину (в байтах) для одного и того же содержимого. Если длина хранимых значений превышает 4000 байт, установленных в NVARCHAR2, то вместо этого следует использовать 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 (когда он всегда применялся как последний фильтр, независимо от того, где в цепочке фильтров он появлялся) устарело. В Django 2.0 фильтр изменится на немедленное применение conditional_escape().
Разное¶
- Опция
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. - Атрибут private
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обесценивается. Добавьтеparent_link=Trueк таким полям. - Приватный API
Widget._format_value()становится публичным и переименовывается вformat_value(). Старое название будет работать в течение периода амортизации. - Приватные методы
FileFieldget_directory_name()иget_filename()устарели в пользу выполнения этой работы вStorage.generate_filename()). - Промежуточные программы старого типа, использующие
settings.MIDDLEWARE_CLASSES, устарели. Adapt old, custom middleware и используйте новую настройку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удалены:- Свойства:
aggregatesи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_related_many_to_many_objects()get_all_related_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(). - Template response APIs принуждают использовать
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. - Агрегатные методы
GeoQuerySetcollect(),extent(),extent3d(),make_line()иunionagg()удалены. - Возможность указать
ContentType.nameпри создании экземпляра типа содержимого удалена. - Поддержка старой сигнатуры
allow_migrateудалена. - Удалена поддержка синтаксиса
{% cycle %}, использующего аргументы, разделенные запятыми. - Предупреждение, которое выдавал
Signerпри указании недопустимого разделителя, теперь является предупреждениемValueError.