Примечания к выпуску 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()
может быть вызван без аргументов, чтобы вернуть все объекты в наборе queryset.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
в представление отладки. - Добавлены методы
HttpResponse
readable()
и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
.
URL-адреса¶
- Добавление в
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()
пользовательского хранилища.- Приватные методы
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()
возвращает кверисет, а не список первичных ключей дляManyToManyField
s. - Если установлен
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
классе конвертируют datetime
из старых методов по мере необходимости и выдают предупреждение об устаревании.
Сторонние бэкенды хранилищ могут сохранять старые методы до тех пор, пока они хотят поддерживать более ранние версии 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
. - Частный атрибут
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()
. Старое название будет работать в течение периода амортизации. - Частные методы
FileField
get_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_ROOTS
TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_DEBUG
TEMPLATE_DIRS
TEMPLATE_LOADERS
TEMPLATE_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
. - Агрегатные методы
GeoQuerySet
collect()
,extent()
,extent3d()
,make_line()
иunionagg()
удалены. - Возможность указать
ContentType.name
при создании экземпляра типа содержимого удалена. - Поддержка старой сигнатуры
allow_migrate
удалена. - Удалена поддержка синтаксиса
{% cycle %}
, использующего аргументы, разделенные запятыми. - Предупреждение, которое
Signer
выдавалось при указании недопустимого разделителя, теперь являетсяValueError
.