2016 年 8 月 1 日
欢迎来到 Django 1.10 版本!
这些发布说明涵盖了 新功能,以及一些 不兼容的更改,在从 Django 1.9 或更早版本升级时,您需要注意这些更改。我们已经 放弃了一些功能,它们已经达到了停用周期的末尾,同时我们已经 开始了一些功能的停用过程。
如果你要更新现有的项目,请看 如何将 Django 更新至新的版本 指南。
与 Django 1.9 一样,Django 1.10 需要 Python 2.7、3.4 或 3.5。我们 强烈建议 并且只正式支持每个系列的最新版本。
django.contrib.postgres
现在包括一个 数据库函数集合,允许使用全文搜索引擎。您可以在关系数据库中跨多个字段进行搜索,将搜索与其他查找组合使用,使用不同的语言配置和权重,以及按相关性对结果进行排名。
它还现在包括 trigram 支持,使用 trigram_similar
查找以及 TrigramSimilarity
和 TrigramDistance
表达式。
引入了一种新的中间件风格,以解决旧式中间件的请求/响应层次不严格的问题,这在 DEP 0005 中有描述。您需要 调整旧的自定义中间件,并从 MIDDLEWARE_CLASSES
设置切换到新的 MIDDLEWARE
设置以充分利用这些改进。
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
添加了 "无日期" 和 "有日期" 选项。
管理后台中嵌入的 jQuery 库已经从 2.1.4 版本升级到 2.2.3 版本。
django.contrib.auth
¶增加了对 Argon2 密码哈希 的支持。它被推荐用于替代 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
¶距离查找 现在接受表达式作为距离值参数。
新的 GEOSGeometry.unary_union
属性计算了此几何对象的所有元素的并集。
新增了 GEOSGeometry.covers()
二元谓词。
新增了 GDALBand.statistics()
方法以及 mean
和 std
属性。
在 MySQL 上新增了对 Difference
、Intersection
和 SymDifference
函数的支持。
新增支持实例化空的 GEOS 几何对象。
新增了 LineString.closed
和 MultiLineString.closed
属性。
如果没有指定特定字段, GeoJSON 序列化程序 现在会在 properties
字典中输出对象的主键。
现在可以在 GDALBand.data()
方法上复制输入数据。可以高效地使用重复的值更新带数据。
新增了数据库函数 IsValid
和 MakeValid
,以及 isvalid
查找,都用于 PostGIS。这允许在数据库端对无效的几何对象进行过滤和修复。
新增了所有 空间查找 的栅格支持。
django.contrib.postgres
¶为了方便起见,HStoreField
现在将其键和值转换为字符串。
django.contrib.sessions
¶clearsessions
管理命令现在会删除基于文件的会话。
django.contrib.sites
¶django.contrib.staticfiles
¶基于文件的缓存后端现在使用最高的 pickling 协议。
默认的 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()
创建的对象上设置主键。
为各种表达式(Func
、When
、Case
和 OrderBy
)的 as_sql()
方法添加了关键字参数,允许数据库后端在不更改 self
的情况下自定义它们,这在使用不同的数据库后端时不安全。参见 Func.as_sql()
的 arg_joiner
和 **extra_context
参数的示例。
存储后端现在提供一个时区感知的 API,具有新的方法 get_accessed_time()
、get_created_time()
和 get_modified_time()
。如果 USE_TZ
为 True
,则它们返回一个时区感知的 datetime
,否则返回本地时区的非时区感知的 datetime
。
新的 Storage.generate_filename()
方法使得更容易实现不使用以前在 FileField
中的 os.path
调用的自定义存储。
如果安装了 django.contrib.staticfiles
,则现在会使用它来提供表单和小部件的 Media
。
由 CharField
渲染的 <input>
标签现在如果字段具有 min_length
,则会包含一个 minlength
属性。
现在,必填表单字段具有 required
HTML 属性。将新的 Form.use_required_attribute
属性设置为 False
可以禁用它。在表单集的表单上不包括 required
属性,因为在添加和删除表单集时,浏览器验证可能不正确。
View
类现在可以从 django.views
中导入。
i18n_patterns()
辅助函数现在可以在使用 request.urlconf
指定的根 URL 配置中使用。
通过将 i18n_patterns()
的新参数 prefix_default_language
设置为 False
,您可以允许在没有 URL 前缀的情况下访问默认语言。
现在,当在 POST
或 GET
中没有 next
参数时,set_language()
对于 AJAX 请求会返回 204 状态码(No Content)。
JavaScriptCatalog
和 JSONCatalog
类视图取代了不推荐使用的 javascript_catalog()
和 json_catalog()
函数视图。新视图与旧视图几乎相同,唯一的区别是,默认情况下,新视图会从所有已安装的应用程序中收集 djangojs
翻译域中的所有 JavaScript 字符串,而不仅仅是来自 LOCALE_PATHS
的 JavaScript 字符串。
现在,call_command()
会返回从 command.handle()
方法返回的值。
新的 check --fail-level
选项允许指定消息级别,该级别将导致命令以非零状态退出。
新的 makemigrations --check
选项在检测到模型更改而没有迁移时,使命令以非零状态退出。
makemigrations
现在会显示生成的迁移文件的路径。
shell --interface
选项现在接受 python
,以强制使用 "plain" Python 解释器。
新的 shell --command
选项允许您以 Django 用户身份运行命令并退出,而不是打开交互式 shell。
如果指定了代理模型(导致没有输出)而没有指定其具体的父模型,dumpdata
现在会显示警告。
新的 BaseCommand.requires_migrations_checks
属性可以设置为 True
,如果您希望您的命令在磁盘上的迁移集与数据库中的迁移不匹配时打印警告,就像 runserver
一样。
为了辅助测试,call_command()
现在接受一个命令对象作为第一个参数。
shell
命令在使用 libedit
的系统上支持制表符自动完成,例如 macOS。
inspectdb
命令允许您通过将表的名称指定为参数来选择应该进行检查的表。
新增支持序列化 enum.Enum
对象。
通过在 Migration
上设置 atomic
属性,添加了对 非原子迁移 的支持。
migrate
和 makemigrations
命令现在会 检查一致的迁移历史。如果它们发现某些已应用的迁移存在未应用的依赖项,将会引发 InconsistentMigrationHistory
异常。
pre_migrate()
和 post_migrate()
信号现在会分发它们的迁移 plan
和 apps
。
来自代理模型的反向外键现在会传播到它们的具体类。指向代理模型的 ForeignKey
所附加的反向关系现在可以作为描述符在代理模型类上访问,并且可以在查询集过滤中引用。
新的 Field.rel_db_type()
方法返回了诸如 ForeignKey
和 OneToOneField
这样指向另一个字段的字段的数据库列数据类型。
新增了 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
设置的 cookie。
django.core.serializers.json.DjangoJSONEncoder
现在知道如何序列化懒惰字符串,通常用于可翻译的内容。
为了更好地捕获错误,TestCase
现在在每个测试结束时检查可延迟的数据库约束。
测试和测试用例可以被 标记为标签 并可以使用新的 test --tag
和 test --exclude-tag
选项进行选择性运行。
即使 django.contrib.sessions
不在 INSTALLED_APPS
中,您现在也可以使用测试客户端登录并使用会话。
在 django.setup()
中的一个新添加允许在请求/响应周期之外发生的 URL 解析(例如在管理命令和独立脚本中)在设置 FORCE_SCRIPT_NAME
时考虑到它。
URLValidator
现在将域名标签的长度限制为 63 个字符,域名的总长度限制为 253 个字符,符合 RFC 1034 的规定。
int_list_validator()
现在接受一个可选的布尔参数 allow_negative
,默认为 False
,以允许负整数。
Warning
除了本节中概述的更改之外,请务必查看 在 1.10 中移除的功能,了解已经到达了弃用周期终点并因此被移除的功能。如果您没有在给定功能的弃用时间表内更新您的代码,它的移除可能会被视为不兼容的更改。
GIS 的 AreaField
使用一个未指定的底层数字类型,实际上可以是任何 Python 数值类型。从数据库中检索到的 decimal.Decimal
值现在被转换为 float
,以便更容易将它们与 GIS 库使用的值结合在一起。
为了启用时间减法,您必须将数据库功能标志 supports_temporal_subtraction
设置为 True
,并实现 DatabaseOperations.subtract_temporals()
方法。该方法应返回计算``lhs`` 和 rhs
参数之间差异的微秒数所需的 SQL 和参数,其数据类型用于存储 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 的上游支持将在 2016 年 9 月结束。因此,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
测试模型已被移除。¶自 Django 1.8 开始为 contrib 应用程序引入迁移以来,这些自定义用户测试模型的表不再创建,使它们无法在测试环境中使用。
在反序列化模型时,不再自动填充应用程序注册表。这在 Django 1.7.2 中添加,是为了允许在 Django 之外反序列化模型,比如在 RQ worker 中,而不需要调用 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 作为默认密码哈希器。
If you have an old Django project with MD5 or SHA1 (even salted) encoded
passwords, be aware that these can be cracked fairly easily with today's
hardware. To make Django users acknowledge continued use of weak hashers, the
following hashers are removed from the default PASSWORD_HASHERS
setting:
"django.contrib.auth.hashers.SHA1PasswordHasher"
"django.contrib.auth.hashers.MD5PasswordHasher"
"django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher"
"django.contrib.auth.hashers.UnsaltedMD5PasswordHasher"
"django.contrib.auth.hashers.CryptPasswordHasher"
考虑使用一个 包装的密码哈希器 来加强数据库中的哈希值。如果这不可行,可以将 PASSWORD_HASHERS
设置添加到您的项目中,并添加回您需要的任何哈希器。
您可以像这样检查您的数据库是否具有任何已删除的哈希器:
from django.contrib.auth import get_user_model
User = get_user_model()
# Unsalted MD5/SHA1:
User.objects.filter(password__startswith="md5$$")
User.objects.filter(password__startswith="sha1$$")
# Salted MD5/SHA1:
User.objects.filter(password__startswith="md5$").exclude(password__startswith="md5$$")
User.objects.filter(password__startswith="sha1$").exclude(password__startswith="sha1$$")
# Crypt hasher:
User.objects.filter(password__startswith="crypt$$")
from django.db.models import CharField
from django.db.models.functions import Length
CharField.register_lookup(Length)
# Unsalted MD5 passwords might not have an 'md5$$' prefix:
User.objects.filter(password__length=32)
Field.get_prep_lookup()
和 Field.get_db_prep_lookup()
方法已被移除。¶如果您有一个自定义字段实现了这两种方法中的任何一种,请为其注册一个自定义查找。例如:
from django.db.models import Field
from django.db.models.lookups import Exact
class MyField(Field): ...
class MyFieldExact(Exact):
def get_prep_lookup(self):
# do_custom_stuff_for_myfield
...
MyField.register_lookup(MyFieldExact)
django.contrib.gis
¶不再支持 SpatiaLite < 3.0 和 GEOS < 3.3 。
add_postgis_srs()
的向后兼容别名已被移除,应使用 django.contrib.gis.utils.add_srs_entry()
。
在 Oracle/GIS 上,Area
聚合函数现在返回一个 float
,而不再是 decimal.Decimal
。(它仍然以平方米为单位包装。)
默认情况下,GEOSGeometry
的表示形式(WKT 输出)现在默认被修剪。也就是说,不再是 POINT (23.0000000000000000 5.5000000000000000)
,而是 POINT (23 5.5)
。
两个新配置有助于减轻通过大型请求发起的拒绝服务攻击:
DATA_UPLOAD_MAX_MEMORY_SIZE
限制请求主体的大小。文件上传不计入此限制。
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
设置已删除,因为自 1.0 版本以来 Django 不再使用它。如果你在项目中使用了它,可以将其添加到项目的设置中。默认值是 '/accounts/logout/'
。
具有 close()
方法的对象,例如文件和生成器,传递给 HttpResponse
现在会立即关闭,而不是在 WSGI 服务器调用响应的 close()
方法时关闭。
在 QuerySet.update_or_create()
中删除了多余的 transaction.atomic()
调用。这可能会影响 TransactionTestCase.assertNumQueries()
测试的查询计数。
在 BaseCommand.execute(**options)
中删除了对 skip_validation
的支持。请改用 skip_checks
(Django 1.7 中添加)来代替。
现在,在指定的夹具文件未找到时,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
,他们将被登出。如果需要以前的行为,请在 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
时,"Save as new" 按钮现在会重定向到新对象的修改视图,而不是模型的变更列表。如果你需要之前的行为,请将新的 ModelAdmin.save_as_continue
属性设置为 False
。
必填的表单字段现在具有 required
HTML 属性。如果要禁用它,请将 Form.use_required_attribute
属性设置为 False
。如果不想要浏览器验证,还可以在 <form>
中添加 novalidate
属性。如果要在自定义小部件上禁用 required
属性,请重写 Widget.use_required_attribute()
方法。
WSGI 处理程序不再从 HEAD
请求或具有 status_code
为 100-199、204 或 304 的响应中删除内容。大多数 Web 服务器已经实现了这种行为。使用 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.clean()
方法中调用了 AbstractBaseUser.normalize_username()
。
私有 API django.forms.models.model_to_dict()
现在返回一个查询集而不是 ManyToManyField
的主键列表。
如果安装了 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
指示符,而不是同名的设置。
不要使用直接分配来分配相关对象:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
使用 Django 1.9 中添加的 set()
方法:
>>> e.related_set.set([obj1, obj2, obj3])
这可以避免因隐式保存导致的分配混淆。
Storage
API¶旧的、非时区感知的方法 accessed_time()
, created_time()
, 和 modified_time()
已被弃用,推荐使用新的 get_*_time()
方法。
第三方存储后端应该实现新的方法并将旧的方法标记为弃用。在此之前,基础的 Storage
类上的新的 get_*_time()
方法将根据需要将来自旧方法的 datetime
转换并在这样做时发出弃用警告。
只要第三方存储后端希望支持早期版本的 Django,它们就可以保留旧方法。
django.contrib.gis
¶GEOSGeometry
的 get_srid()
和 set_srid()
方法已被弃用,推荐使用 srid
属性。
Point
的 get_x()
, set_x()
, get_y()
, set_y()
, get_z()
, 和 set_z()
方法已被弃用,推荐使用 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
使用不同的数据库字段类型(NVARCHAR2
)而不是 CommaSeparatedIntegerField
(VARCHAR2
)。根据您的数据库设置,这可能意味着相同内容的不同编码,从而导致相同内容的不同字节长度。如果您存储的值长于 NVARCHAR2
的 4000 字节限制,您应该改用 TextField
(NCLOB
)。在这种情况下,如果您有任何按字段分组的查询(例如,使用聚合注释模型或使用 distinct()
),您需要更改它们(以延迟字段)。
__search
查询查找¶search
查询查找已被弃用,它仅支持 MySQL,并且功能非常有限。请将其替换为自定义查询查找:
from django.db import models
class Search(models.Lookup):
lookup_name = "search"
def as_mysql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return "MATCH (%s) AGAINST (%s IN BOOLEAN MODE)" % (lhs, rhs), params
models.CharField.register_lookup(Search)
models.TextField.register_lookup(Search)
User.is_authenticated()
和 User.is_anonymous()
作为方法。¶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
的 "escape" 部分¶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
的旧式中间件已被弃用。请 适应旧的自定义中间件 并使用新的 MIDDLEWARE
设置。
这些功能已经完成了弃用周期,并在 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
中使用不正确数量的解包值将引发异常,而不是默默失败。
使用点分隔的 Python 路径反向 reverse()
URL 的能力已被移除。
使用点分隔的 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()
django.forms.RegexField
的 error_message
参数已被移除。
unordered_list
过滤器不再支持旧式列表。
不再支持将字符串 view
参数传递给 url()
。
将 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
属性已被移除。
允许不为其 form_class
参数定义默认值的 FormMixin.get_form()
的向后兼容性修复已被移除。
以下设置已被移除,您必须升级到 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
。
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()
会话验证现在已启用,无论是否在 MIDDLEWARE_CLASSES
中包含 'django.contrib.auth.middleware.SessionAuthenticationMiddleware'
。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
。
5月 02, 2025