Django 1.10 发行说明 — Django 文档
Django 1.10 发行说明
2016 年 8 月 1 日
欢迎来到 Django 1.10!
这些发行说明涵盖了 新功能 ,以及从 Django 1.9 或更旧版本升级时您需要注意的一些 向后不兼容更改 。 我们已经 删除了一些已达到弃用周期结束的功能 ,并且我们已经 开始了一些功能 的弃用过程。
如果您要更新现有项目,请参阅 将 Django 升级到更新版本 指南。
Python兼容性
与 Django 1.9 一样,Django 1.10 需要 Python 2.7、3.4 或 3.5。 我们【X3X】强烈推荐【X23X】,官方只支持各系列的最新版本。
Django 1.10 中的新功能
PostgreSQL 全文检索
django.contrib.postgres
现在包含 数据库函数集合 ,以允许使用全文搜索引擎。 您可以搜索关系数据库中的多个字段,将搜索与其他查找结合起来,使用不同的语言配置和权重,并按相关性对结果进行排名。
它还现在包括三元组支持,使用 :lookup:`trigram_similar` 查找和 TrigramSimilarity 和 TrigramDistance 表达式。
新型中间件
引入了一种新型中间件,以解决DEP 0005中描述的旧式中间件缺乏严格的请求/响应分层。 您需要 调整旧的自定义中间件 并从 MIDDLEWARE_CLASSES
设置切换到新的 :setting:`MIDDLEWARE` 设置以利用这些改进。
官方支持 Unicode 用户名
django.contrib.auth
中的 User 模型最初只接受用户名中的 ASCII 字母和数字。 尽管这不是故意的选择,但在使用 Python 3 时总是接受 Unicode 字符。
用户名验证器现在仅在 Python 3 上默认明确接受 Unicode 字符。
自定义用户模型可以使用新的 ASCIIUsernameValidator 或 UnicodeUsernameValidator。
小功能
django.contrib.admin
- 对于在子路径上运行的站点,如果设置,每个管理页面顶部的“查看站点”链接 的默认 URL 现在将指向
request.META['SCRIPT_NAME']
,而不是/
]。 - 添加或编辑对象后出现的成功消息现在包含指向对象更改表单的链接。
- 所有内联 JavaScript 都已删除,因此您可以根据需要启用
Content-Security-Policy
HTTP 标头。 - 新的 InlineModelAdmin.classes 属性允许在内联字段集上指定类。 带有
collapse
类的内联最初将被折叠,并且它们的标题将有一个小的“显示”链接。 - 如果用户没有添加权限,现在将呈现模型更改列表上的
object-tools
块(没有添加按钮)。 这使得在这种情况下更容易添加自定义工具。 - LogEntry 模型现在以 JSON 结构存储更改消息,以便可以使用当前活动语言动态翻译消息。 新的
LogEntry.get_change_message()
方法现在是检索更改消息的首选方法。 ModelAdmin.raw_id_fields
中字段的选定对象现在具有指向对象更改表单的链接。- 如果字段可为空,则为
DateFieldListFilter
添加了“无日期”和“有日期”选项。 - 嵌入在 admin 中的 jQuery 库从版本 2.1.4 升级到 2.2.3。
django.contrib.auth
- 添加了对 Argon2 密码哈希 的支持。 推荐使用 PBKDF2,但是,它不是默认设置,因为它需要第三方库。
- PBKDF2 密码哈希器的默认迭代计数增加了 25%。 这种向后兼容的更改不会影响子类化
django.contrib.auth.hashers.PBKDF2PasswordHasher
的用户更改默认值。 django.contrib.auth.views.logout()
视图发送“无缓存”标头以防止出现 Safari 缓存重定向并阻止用户注销的问题。- 将可选的
backend
参数添加到 django.contrib.auth.login() 以允许在没有凭据的情况下使用它。 - 新的 :setting:`LOGOUT_REDIRECT_URL` 设置控制
django.contrib.auth.views.logout()
视图的重定向,如果视图没有获得next_page
参数。 django.contrib.auth.views.login()
视图的新redirect_authenticated_user
参数允许重定向访问登录页面的经过身份验证的用户。- 新的 AllowAllUsersModelBackend 和 AllowAllUsersRemoteUserBackend 忽略了
User.is_active
的值,而 ModelBackend 和 Remote17activeUserBackendremote17activeUserBackend 忽略了值。
django.contrib.gis
- 距离查找现在接受表达式作为距离值参数。
- 新的 GEOSGeometry.unary_union 属性计算此几何的所有元素的并集。
- 添加了 GEOSGeometry.covers() 二进制谓词。
- 添加了 GDALBand.statistics() 方法和 mean 和 std 属性。
- 在 SpatiaLite 上添加了对 MakeLine 聚合和 GeoHash 函数的支持。
- 添加了对 MySQL 上的 Difference、Intersection 和 SymDifference 函数的支持。
- 添加了对实例化空 GEOS 几何图形的支持。
- WKTWriter 的新 trim 和 precision 属性允许控制 WKT 中坐标小数部分的输出。
- 添加了 LineString.closed 和 MultiLineString.closed 属性。
- 如果未指定特定字段,GeoJSON 序列化器 现在输出
properties
字典中对象的主键。 - 添加了在 GDALBand.data() 方法上复制输入数据的能力。 现在可以使用重复值有效地更新波段数据。
- 添加了数据库函数 IsValid 和 MakeValid,以及 :lookup:`isvalid` 查找,全部用于 PostGIS。 这允许在数据库端过滤和修复无效的几何图形。
- 添加了对所有 空间查找 的栅格支持。
django.contrib.staticfiles
- :ttag:`static` 模板标签现在使用
django.contrib.staticfiles
如果它在INSTALLED_APPS
中。 这对于现在可以始终使用{% load static %}
(而不是{% load staticfiles %}
或{% load static from staticfiles %}
)的第三方应用特别有用,并且不用担心staticfiles
] 应用程序已安装。 - 您可以使用自定义
AppConfig
更轻松地 自定义collectstatic --ignore
选项。
缓存
- 基于文件的缓存后端现在使用最高的酸洗协议。
CSRF
- 默认 :setting:`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
的情况下自定义它们,这在使用不同的数据库后端时是不安全的。 有关示例,请参阅 Func.as_sql() 的arg_joiner
和**extra_context
参数。
文件存储
- 存储后端现在提供具有新方法 get_accessed_time()、get_created_time() 和 get_modified_time() 的时区感知 API。 如果 :setting:`USE_TZ` 是
True
,则它们返回时区感知datetime
,否则返回本地时区中的原始datetime
。 - 新的 Storage.generate_filename() 方法可以更轻松地实现不使用之前在 FileField 中调用
os.path
的自定义存储。
表格
- 如果安装了表单和小部件
Media
,现在使用 django.contrib.staticfiles 提供服务。 - 如果字段具有
min_length
,则由 CharField 渲染的<input>
标签现在包含minlength
属性。 - 必填表单字段现在具有
required
HTML 属性。 将新的 Form.use_required_attribute 属性设置为False
以禁用它。required
属性不包含在表单集的表单中,因为在添加和删除表单集时浏览器验证可能不正确。
国际化
- i18n_patterns() 辅助函数现在可以在使用 request.urlconf 指定的根 URLConf 中使用。
- 通过将 i18n_patterns() 的新
prefix_default_language
参数设置为False
,您可以允许在没有 URL 前缀的情况下访问默认语言。 - 当
POST
或GET
中没有next
参数时,set_language() 现在为 AJAX 请求返回 204 状态代码(无内容)。 - JavaScriptCatalog 和 JSONCatalog 基于类的视图取代了已弃用的
javascript_catalog()
和json_catalog()
基于函数的视图。 新视图几乎等同于旧视图,除了默认情况下,新视图从所有已安装的应用程序收集djangojs
翻译域中的所有 JavaScript 字符串,而不仅仅是来自 :setting:`LOCALE_PATHS 的 JavaScript 字符串`。
管理命令
- call_command() 现在返回从
command.handle()
方法返回的值。 - 新的
check --fail-level
选项允许指定将导致命令以非零状态退出的消息级别。 - 当检测到没有迁移的模型更改时,新的
makemigrations --check
选项使命令以非零状态退出。 - :djadmin:`makemigrations` 现在显示它生成的迁移文件的路径。
shell --interface
选项现在接受python
以强制使用“普通”Python 解释器。- 新的
shell --command
选项允许您以 Django 的身份运行命令并退出,而不是打开交互式 shell。 - 如果指定了代理模型(导致没有输出)而没有其具体的父模型,则向 :djadmin:`dumpdata` 添加警告。
- 新的 BaseCommand.requires_migrations_checks 属性可以设置为
True
如果您希望您的命令打印警告,例如 :djadmin:`runserver` 确实如此,如果设置磁盘上的迁移与数据库中的迁移不匹配。 - 为了协助测试,call_command() 现在接受一个命令对象作为第一个参数。
- :djadmin:`shell` 命令支持使用
libedit
的系统上的制表符补全,例如 苹果系统。 - :djadmin:`inspectdb` 命令允许您通过指定表名作为参数来选择应该检查哪些表。
迁移
- 添加了对
enum.Enum
对象序列化的支持。 - 向 RunSQL 和 RunPython 操作添加了
elidable
参数,以允许在压缩迁移时删除它们。 - 通过在
Migration
上设置atomic
属性,添加了对 非原子迁移 的支持。 migrate
和makemigrations
命令现在 检查一致的迁移历史 。 如果他们发现应用迁移的一些未应用的依赖项,则会引发InconsistentMigrationHistory
。- pre_migrate() 和 post_migrate() 信号现在发送它们的迁移
plan
和apps
。
型号
- 来自代理模型的反向外键现在传播到它们的具体类。 由指向代理模型的 ForeignKey 附加的反向关系现在可以作为代理模型类上的描述符访问,并且可以在查询集过滤中引用。
- 新的 Field.rel_db_type() 方法返回指向另一个字段的字段(例如
ForeignKey
和OneToOneField
)的数据库列数据类型。 - arity 类属性被添加到 Func。 此属性可用于设置函数接受的参数数量。
- 添加了 BigAutoField,它的作用很像 AutoField,除了它保证适合从
1
到9223372036854775807
的数字。 - QuerySet.in_bulk() 可以在没有任何参数的情况下调用以返回查询集中的所有对象。
- related_query_name 现在支持使用
'%(app_label)s'
和'%(class)s'
字符串的应用标签和类插值。 - 允许覆盖从抽象基类继承的模型字段。
- prefetch_related_objects() 函数现在是一个公共 API。
- QuerySet.bulk_create() 在使用 PostgreSQL 时设置对象的主键。
- 添加了 Cast 数据库功能。
- 代理模型现在可以继承多个共享一个公共非抽象父类的代理模型。
- 添加了 Extract 函数以将日期时间组件提取为整数,例如年和小时。
- 添加了 Trunc 函数以将日期或日期时间截断为重要组件。 它们启用诸如每日销售额或每小时销售额之类的查询。
Model.__init__()
现在从其关键字参数设置虚拟字段的值。- 新的 Meta.base_manager_name 和 Meta.default_manager_name 选项允许分别控制 _base_manager 和 _default_manager。
请求和响应
- 在调试视图中添加了
request.user
。 - 添加 HttpResponse 方法 readable() 和 seekable() 使实例成为类流对象并允许用
io.TextIOWrapper
包装它。 - 添加了从
CONTENT_TYPE
标头解析的 HttpRequest.content_type 和 content_params 属性。 request.COOKIES
的解析器被简化以更好地匹配浏览器的行为。request.COOKIES
现在可能包含根据 RFC 6265 无效的 cookie,但可以通过document.cookie
进行设置。
序列化
django.core.serializers.json.DjangoJSONEncoder
现在知道如何序列化惰性字符串,通常用于可翻译的内容。
模板
- 向 DjangoTemplates 后端和 Engine 类添加了
autoescape
选项。 - 将
is
和is not
比较运算符添加到 :ttag:`if` 标签。 - 允许 :tfilter:`dictsort` 按指定索引处的元素对列表列表进行排序。
- debug() 上下文处理器包含对所有数据库别名的查询,而不仅仅是默认别名。
- 添加了对 :ttag:`extends` 和 :ttag:`include` 模板标签的字符串参数的相对路径支持。
测试
- 为了更好地捕捉错误,TestCase 现在在每次测试结束时检查可延迟的数据库约束。
- 测试和测试用例可以用 标记 并使用新的
test --tag
和test --exclude-tag
选项有选择地运行。 - 即使 django.contrib.sessions 不在 :setting:`INSTALLED_APPS` 中,您现在也可以登录并使用测试客户端的会话。
验证器
- URLValidator 现在根据 RFC 1034 将域名标签长度限制为 63 个字符,域名总长度限制为 253 个字符。
- int_list_validator() 现在接受一个可选的
allow_negative
布尔参数,默认为False
,以允许负整数。
1.10 中向后不兼容的更改
数据库后端API
- GIS 的
AreaField
使用未指定的底层数字类型,实际上可以是任何 Python 数字类型。 从数据库中检索到的decimal.Decimal
值现在转换为float
,以便更容易地将它们与 GIS 库使用的值结合起来。 - 为了启用时间减法,您必须将
supports_temporal_subtraction
数据库功能标志设置为True
并实现DatabaseOperations.subtract_temporals()
方法。 此方法应返回计算用于存储 DurationField 的数据类型中lhs
和rhs
参数之间的微秒差异所需的 SQL 和参数。
_meta.get_fields() 为代理模型返回一致的反向字段
在 Django 1.10 之前,与代理的具体类相比,get_fields() 方法在代理模型上调用时返回不同的反向字段。 在这两种情况下,通过返回指向具体类或其代理之一的完整字段集来修复这种不一致。
AbstractUser.username max_length increased to 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 年 9 月结束。 因此,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 测试模型被移除
由于在 Django 1.8 中为 contrib 应用程序引入了迁移,因此不再创建这些自定义用户测试模型的表,使它们在测试上下文中无法使用。
在 Django 之外解压模型时,应用程序注册表不再自动填充
解压模型时,应用程序注册表不再自动填充。 这是在 Django 1.7.2 中添加的,试图允许在 Django 之外解开模型,例如在 RQ 工作器中,而不调用 django.setup()
,但它会造成死锁的可能性。 为了在 RQ 的情况下调整您的代码,您可以 提供您自己的工作脚本 调用 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 作为默认密码哈希器。
如果您有一个带有 MD5 或 SHA1(甚至是加盐的)编码密码的旧 Django 项目,请注意,使用当今的硬件可以很容易地破解这些密码。 为了让 Django 用户承认继续使用弱哈希,以下哈希从默认的 :setting:`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'
考虑使用 包装的密码散列器 来加强数据库中的散列。 如果这不可行,请将 :setting:`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。
- 删除了
django.contrib.gis.utils.add_srs_entry()
的add_postgis_srs()
向后兼容性别名。 - 在 Oracle/GIS 上,Area 聚合函数现在返回
float
而不是decimal.Decimal
。 (它仍然包裹在一平方米的范围内。) - 默认的 GEOSGeometry 表示(WKT 输出)在默认情况下被修剪。 也就是说,您将得到
POINT (23 5.5)
,而不是POINT (23.0000000000000000 5.5000000000000000)
。
请求体的最大大小和 GET/POST 参数的数量是有限的
两个新设置有助于通过大型请求缓解拒绝服务攻击:
- :setting:`DATA_UPLOAD_MAX_MEMORY_SIZE` 限制请求正文的大小。 文件上传不计入此限制。
- :setting:`DATA_UPLOAD_MAX_NUMBER_FIELDS` 限制解析的 GET/POST 参数的数量。
接收异常大表单帖子的应用程序可能需要调整这些设置。
杂项
QuerySet
的repr()
包含在<QuerySet >
中,以便在调试时将其与普通列表消除歧义。utils.version.get_version()
返回 PEP 440 兼容发布候选版本(例如 '1.10rc1' 而不是 '1.10c1')。- CSRF 令牌值现在要求是 64 个字母数字的字符串; 旧版本的 Django 默认设置的 32 个字母数字的值会自动替换为 64 个字符的字符串。 其他值被视为无效。 这只会影响替换这些令牌的开发人员或用户。
LOGOUT_URL
设置被删除,因为 Django 自 1.0 之前就没有使用过它。 如果你在你的项目中使用它,你可以将它添加到你的项目设置中。 默认值为'/accounts/logout/'
。- 具有
close()
方法的对象(例如传递给 HttpResponse 的文件和生成器)现在会立即关闭,而不是在 WSGI 服务器对响应调用close()
时关闭。 - 删除了
QuerySet.update_or_create()
中冗余的transaction.atomic()
调用。 这可能会影响TransactionTestCase.assertNumQueries()
测试的查询计数。 - 移除了
BaseCommand.execute(**options)
中对skip_validation
的支持。 改用skip_checks
(在 Django 1.7 中添加)。 - :djadmin:`loaddata` 现在会引发
CommandError
而不是在找不到指定的夹具文件时显示警告。 - 现在最好调用
LogEntry.get_change_message()
方法,而不是直接访问LogEntry.change_message
属性,该方法将以当前语言提供消息。 - 如果指定了不存在的
template_name
,则默认错误视图现在会引发TemplateDoesNotExist
。 - 删除了
Select
和SelectMultiple
小部件的render()
方法中未使用的choices
关键字参数。render_options()
方法的choices
参数也被删除,使selected_choices
成为第一个参数。 - 违反可延迟数据库约束的测试现在在支持可延迟约束的数据库上运行时会出错。
- 内置管理命令现在使用
options
中的键索引,例如options['verbosity']
,而不是options.get()
并且不再执行任何类型的强制。 如果您使用Command.execute()
(绕过设置默认值的参数解析器)而不是 call_command() 调用命令,这可能是一个问题。 不是调用Command.execute()
,而是将命令对象作为第一个参数传递给call_command()
。 - ModelBackend 和 RemoteUserBackend 现在拒绝非活动用户。 这意味着非活动用户如果从
is_active=True
切换到False
,将无法登录并将被注销。 如果您需要以前的行为,请改用 :setting:`AUTHENTICATION_BACKENDS` 中的新 AllowAllUsersModelBackend 或 AllowAllUsersRemoteUserBackend。 - 鉴于之前的更改,测试客户端的 login() 方法不再总是拒绝非活动用户,而是将此决定委托给身份验证后端。 force_login() 还将决定委托给身份验证后端,因此如果您使用默认后端,则需要使用活动用户。
- django.views.i18n.set_language() 现在可以为 AJAX 请求返回 204 状态代码。
- RangeField 的
base_field
属性现在是一种字段类型,而不是字段的实例。 如果您创建了 RangeField 的自定义子类,则应更改base_field
属性。 - 中间件类现在在服务器启动时而不是在第一次请求期间初始化。
- 如果在自定义用户模型中覆盖
is_authenticated()
或is_anonymous()
,则必须将它们转换为属性或属性,如 弃用说明 中所述。 - 使用 ModelAdmin.save_as=True 时,“另存为新”按钮现在重定向到新对象的更改视图,而不是模型的更改列表。 如果您需要之前的行为,请将新的 ModelAdmin.save_as_continue 属性设置为
False
。 - 必填表单字段现在具有
required
HTML 属性。 将 Form.use_required_attribute 属性设置为False
以禁用它。 如果您不想进行浏览器验证,您还可以将novalidate
属性添加到<form>
。 要禁用自定义小部件上的required
属性,请覆盖 Widget.use_required_attribute() 方法。 - WSGI 处理程序不再从
HEAD
请求或status_code
为 100-199、204 或 304 的响应中删除响应的内容。 大多数 Web 服务器已经实现了这种行为。 使用 Django 测试客户端检索到的响应继续应用这些“响应修复”。 Model.__init__()
现在接收django.db.models.DEFERRED
作为延迟字段的值。- 当使用
QuerySet.defer()
和only()
时,Model._deferred
属性作为动态模型类被删除。 - 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
被删除。 新的 Trnc 表达式提供了相同的功能。 _base_manager
和_default_manager
属性从模型实例中删除。 它们在模型类上仍然可以访问。- 访问模型实例上已删除的字段,例如 在
del obj.field
之后,重新加载字段的值而不是提高AttributeError
。 - 如果您子类化
AbstractBaseUser
并覆盖clean()
,请确保它调用super()
。 AbstractBaseUser.normalize_username() 在新的 AbstractBaseUser.clean() 方法中被调用。 - 私有 API
django.forms.models.model_to_dict()
返回一个查询集,而不是ManyToManyField
的主键列表。 - 如果安装了
django.contrib.staticfiles
,:ttag:`static` 模板标签使用staticfiles
存储来构造 URL,而不是简单地将值与STATIC_ROOT
连接起来]。 新方法对 URL 进行编码,这可能会向后不兼容,例如在路径中包含片段,例如{% static 'img.svg#fragment' %}
,因为#
被编码为%23
。 为了适应,将片段移到模板标签之外:{% static 'img.svg' %}#fragment
。 - 当 :setting:`USE_L10N` 为
True
时,本地化现在应用于 :tfilter:`date` 和 :tfilter:`time`[ X132X] 在未指定格式字符串时进行过滤。 使用来自活动语言环境的DATE_FORMAT
和TIME_FORMAT
说明符代替同名的设置。
1.10 中弃用的功能
直接分配给反向外键或多对多关系
而不是使用直接分配来分配相关对象:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
使用 Django 1.9 中添加的 set() 方法:
>>> e.related_set.set([obj1, obj2, obj3])
这可以防止混淆导致隐式保存的赋值。
非时区感知 存储 API
旧的非时区感知方法 accessed_time()
、created_time()
和 modified_time()
已弃用,取而代之的是新的 get_*_time()
方法。
第三方存储后端应实施新方法并将旧方法标记为已弃用。 在此之前,基础 Storage 类上的新 get_*_time()
方法会根据需要从旧方法转换 datetime
,并在执行此操作时发出弃用警告。
第三方存储后端可能会保留旧方法,只要他们希望支持早期版本的 Django。
django.contrib.gis
- GEOSGeometry 的
get_srid()
和set_srid()
方法已弃用,取而代之的是 srid 属性。 get_x()
、set_x()
、get_y()
、set_y()
、get_z()
和set_z()
方法点[ X93X] 已弃用,取而代之的是x
、y
和z
属性。- Point 的
get_coords()
和set_coords()
方法已被弃用,取而代之的是tuple
属性。 - MultiPolygon 的
cascaded_union
属性已弃用,取而代之的是 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
使用与 CommaSeparatedIntegerField
(VARCHAR2
) 不同的数据库字段类型 (NVARCHAR2
)。 根据您的数据库设置,这可能意味着不同的编码,因此相同内容的长度(以字节为单位)不同。 如果您存储的值超过 NVARCHAR2
的 4000 字节限制,您应该使用 TextField
(NCLOB
) 代替。 在这种情况下,如果您有任何按字段分组的查询(例如 使用聚合或使用 distinct()
注释模型)您需要更改它们(以推迟字段)。
__search 查询查找
search
查找仅支持 MySQL 且功能极其有限,已弃用。 用自定义查找替换它:
from django.db import models
class Search(models.Lookup):
lookup_name = 'search'
def as_mysql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return 'MATCH (%s) AGAINST (%s IN BOOLEAN MODE)' % (lhs, rhs), params
models.CharField.register_lookup(Search)
models.TextField.register_lookup(Search)
使用 User.is_authenticated() 和 User.is_anonymous() 作为方法
AbstractBaseUser 和 AnonymousUser 类的 is_authenticated()
和 is_anonymous()
方法现在是属性。 在 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
。 Model._meta
的私有属性virtual_fields
已弃用,取而代之的是private_fields
。Field.contribute_to_class()
中的私有关键字参数virtual_only
和Model._meta.add_field()
中的virtual
已弃用,取而代之的是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
的旧式中间件。 改编旧的、自定义的中间件 并使用新的 :setting:`MIDDLEWARE` 设置。
1.10 中删除的功能
这些功能已达到弃用周期的终点,并在 Django 1.10 中删除。 有关详细信息,包括如何删除这些功能的使用,请参阅 1.8 中弃用的功能。
- 删除了对直接调用
SQLCompiler
作为调用其quote_name_unless_alias
方法的别名的支持。 cycle
和firstof
模板标签从future
模板标签库中删除。django.conf.urls.patterns()
被移除。- 删除了对
django.conf.urls.i18n.i18n_patterns()
的prefix
参数的支持。 SimpleTestCase.urls
被移除。- 在
for
模板标签中使用不正确的解压值计数会引发异常而不是静默失败。 - 删除了使用虚线 Python 路径 reverse() URL 的功能。
- 删除了对
LOGIN_URL
和LOGIN_REDIRECT_URL
设置使用虚线 Python 路径的功能。 - 自定义管理命令不再支持
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
被移除。- 从 django.db.models.options.Options (
Model._meta
) 中删除了以下私有 API: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()
django.forms.RegexField
的error_message
参数被删除。unordered_list
过滤器不再支持旧样式列表。- 删除了对
url()
字符串view
参数的支持。 - 删除了将
django.forms.Form._has_changed()
重命名为has_changed()
的向后兼容垫片。 removetags
模板过滤器被移除。- 移除了
django.utils.html
中的remove_tags()
和strip_entities()
功能。 django.contrib.auth.views.password_reset()
的is_admin_site
参数被删除。django.db.models.field.subclassing.SubfieldBase
被移除。django.utils.checksums
被移除。django.contrib.admin.helpers.InlineAdminForm
上的original_content_type_id
属性被移除。- 删除了允许定义
FormMixin.get_form()
且其form_class
参数没有默认值的向后兼容性垫片。 - 删除了以下设置,您必须升级到 :setting:`TEMPLATES` 设置:
ALLOWED_INCLUDE_ROOTS
TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_DEBUG
TEMPLATE_DIRS
TEMPLATE_LOADERS
TEMPLATE_STRING_IF_INVALID
- 向后兼容别名
django.template.loader.BaseLoader
被删除。 - get_template() 和 select_template() 返回的 Django 模板对象不再接受 render() 方法中的 Context。
- 模板响应 API 强制使用
dict
和后端相关模板对象,而不是分别使用 Context 和 Template。 - 删除了以下函数和类的
current_app
参数:django.shortcuts.render()
django.template.Context()
django.template.RequestContext()
django.template.response.TemplateResponse()
- 删除了以下功能的
dictionary
和context_instance
参数:django.shortcuts.render()
django.shortcuts.render_to_response()
django.template.loader.render_to_string()
- 删除了以下功能的
dirs
参数:django.template.loader.get_template()
django.template.loader.select_template()
django.shortcuts.render()
django.shortcuts.render_to_response()
- 无论
'django.contrib.auth.middleware.SessionAuthenticationMiddleware'
是否在MIDDLEWARE_CLASSES
中,都会启用会话验证。SessionAuthenticationMiddleware
不再有任何用途,可以从MIDDLEWARE_CLASSES
中移除。 在 Django 2.0 之前,它一直作为存根保留,以供不阅读本说明的用户使用。 - 私有属性
django.db.models.Field.related
被移除。 - 删除了
migrate
管理命令的--list
选项。 ssi
模板标签被移除。- 删除了对
if
模板标签中的=
比较运算符的支持。 - 删除了允许在没有
max_length
参数的情况下定义Storage.get_available_name()
和Storage.save()
的向后兼容性垫片。 - 移除了
ModelFormMixin.success_url
中对旧版%(<foo>)s
语法的支持。 GeoQuerySet
聚合方法collect()
、extent()
、extent3d()
、make_line()
和unionagg()
被删除。- 删除了在创建内容类型实例时指定
ContentType.name
的功能。 - 删除了对
allow_migrate
旧签名的支持。 - 删除了对使用逗号分隔参数的
{% cycle %}
语法的支持。 - Signer 在给定无效分隔符时发出的警告现在是
ValueError
。