Примечания к выпуску 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
в представление отладки. - Добавлены методы
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
.
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 или переопределите ее своей собственной, вам нужно будет добавить соответствующую конфигурацию логирования, если вы хотите видеть этот вывод:
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
были удалены¶
После введения миграций для приложений 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
s из старых методов по мере необходимости и выдают предупреждение об устаревании.
Сторонние бэкенды хранилищ могут сохранять старые методы до тех пор, пока они хотят поддерживать более ранние версии 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()
. Старое название будет работать в течение периода амортизации. - Приватные методы
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
.