Django 1.11 版本发行说明¶
2017 年 4 月 4 日
欢迎来到 Django 1.11 版本!
这些发布说明涵盖了 新功能,以及一些 不兼容变更,当您从 Django 1.10 或更早版本升级时,您需要注意。我们已经 开始了一些功能的弃用过程。
如果你要更新现有的项目,请看 如何将 Django 更新至新的版本 指南。
Django 1.11 被指定为 长期支持版本。它将在发布后至少三年内接收安全更新。对于之前的 LTS 版本 Django 1.8,支持将于 2018 年 4 月结束。
Python 兼容性¶
Django 1.11 需要 Python 2.7、3.4、3.5、3.6 或 3.7(截止到 1.11.17 版本)。我们* 强烈建议* 并且只正式支持每个系列的最新版本。
Django 1.11.x 系列是支持 Python 2 的最后一个版本。下一个主要版本,Django 2.0,将仅支持 Python 3.4+。
弃用警告默认不再大声发出¶
与旧版本的 Django 不同,Django 自身的弃用警告默认不再显示。这与 Python 的默认行为一致。
此更改允许第三方应用在不添加用于避免弃用警告的代码的情况下同时支持 Django 1.11 LTS 和 Django 1.8 LTS 。
在发布 Django 2.0 后,我们建议第三方应用的作者停止支持所有在 1.11 之前的 Django 版本。在那时,您应该能够使用 python -Wd 运行您包的测试,以确保弃用警告出现。在修复弃用警告后,您的应用应该与 Django 2.0 兼容。
Django 1.11 新特性¶
基于类的模型索引¶
新的 django.db.models.indexes 模块包含了用于简化创建数据库索引的类。索引可以通过在模型中使用 Meta.indexes 选项来添加。
Index 类创建一个 b-tree 索引,就像你在模型字段上使用 db_index 或在模型 Meta 类上使用 index_together 一样。它可以被子类化以支持不同的索引类型,例如 GinIndex。它还允许定义索引列的顺序(ASC/DESC)。
基于模板的小部件渲染¶
为了方便定制小部件,现在表单小部件的渲染是使用模板系统而不是在 Python 中进行的。请参阅 表单渲染 API。
你可能需要调整你编写的任何自定义小部件,以适应一些 不兼容变更。
Subquery 表达式¶
新的 Subquery 和 Exists 数据库表达式允许创建明确的子查询。子查询可以使用 OuterRef 类引用来自外部查询集的字段。
次要特性¶
django.contrib.admin¶
ModelAdmin.date_hierarchy现在可以引用跨关联的字段。新的
ModelAdmin.get_exclude()钩子允许根据请求或模型实例指定要排除的字段。popup_response.html模板现在可以按照每个应用程序、每个模型或通过设置ModelAdmin.popup_response_template属性来进行覆盖。
django.contrib.auth¶
PBKDF2 密码哈希器的默认迭代次数增加了 20 %。
LoginView和LogoutView基于类的视图替代了已弃用的login()和logout()基于函数的视图。PasswordChangeView、PasswordChangeDoneView、PasswordResetView、PasswordResetDoneView、PasswordResetConfirmView和PasswordResetCompleteView基于类的视图替代了已弃用的password_change(),password_change_done(),password_reset(),password_reset_done(),password_reset_confirm(), 和password_reset_complete()基于函数的视图。PasswordResetConfirmView的新属性post_reset_login允许在成功重置密码后自动登录用户。如果配置了多个AUTHENTICATION_BACKENDS,可以使用post_reset_login_backend属性选择要使用的后端。为了避免通过 HTTP Referer 标头泄露密码重置令牌的可能性(例如,如果重置页面包含对托管在另一个域上的 CSS 或 JavaScript 的引用),
PasswordResetConfirmView(但不是已弃用的password_reset_confirm()基于函数的视图)将令牌存储在会话中,并重定向到自身,以向用户呈现不带令牌的 URL 的密码更改表单。update_session_auth_hash()现在会旋转会话密钥,以允许密码更改来使被窃取的会话 Cookie 失效。LoginView和LogoutView的新属性success_url_allowed_hosts允许指定一组安全的主机,用于在登录和注销后进行重定向。已添加密码验证器的
help_text到UserCreationForm。HttpRequest现在传递给authenticate(),如果身份验证后端接受request参数,则它将传递给身份验证后端。user_login_failed()信号现在接收一个request参数。PasswordResetForm支持自定义用户模型,该模型使用名称不是'email'的电子邮件字段。将CustomUser.EMAIL_FIELD设置为字段的名称。get_user_model()现在可以在导入时调用,即使在定义模型的模块中也可以。
django.contrib.contenttypes¶
在
remove_stale_contenttypes命令中,当检测到陈旧的内容类型时,现在会列出一系列相关对象,如auth.Permission,这些对象也将被删除。之前,只列出了内容类型(而且此提示是在migrate之后,而不是在一个单独的命令中)。
django.contrib.gis¶
新的
GEOSGeometry.from_gml()和OGRGeometry.from_gml()方法允许从 GML 创建几何图形。在 SpatiaLite 上新增了对
dwithin查询的支持。基于 OpenLayers 的表单小部件现在使用来自
https://cdnjs.cloudflare.com的OpenLayers.js,这比旧的https://openlayers.org/源更适合生产使用。它们还更新为使用 OpenLayers 3。PostGIS 迁移现在可以改变字段尺寸。
现在可以在创建
GDALRaster对象时传递size、shape和offset参数。新增了对 Oracle 数据库的支持,包括
AsGML函数、BoundingCircle函数、IsValid函数以及isvalid查询。
django.contrib.postgres¶
StringAgg的新参数distinct决定了连接的值是否要去重。django.contrib.postgres.fields.JSONField接受一个新的参数encoder,用于指定自定义类以编码不受标准编码器支持的数据类型。新的
CIText混合类和CITextExtension迁移操作允许在 PostgreSQL 中使用citext扩展来进行不区分大小写的查找。提供了三个字段:CICharField、CIEmailField和CITextField。新的
JSONBAgg允许将值聚合为 JSON 数组。HStoreField(模型字段)和HStoreField(表单字段)允许存储空值。
缓存¶
Memcached 后端现在将
OPTIONS的内容作为关键字参数传递给客户端构造函数,允许更高级的客户端行为控制。请参阅 cache arguments 文档以获取示例。Memcached 后端现在允许在
LOCATION中定义多个服务器,使用逗号分隔的字符串,以方便处理使用这种字符串的环境变量的第三方服务。
CSRF¶
新增了
CSRF_USE_SESSIONS设置,允许将 CSRF 令牌存储在用户的会话中,而不是在 cookie 中。
数据库后端¶
在 PostgreSQL 9.5+ 和 Oracle 上,新增了
skip_locked参数,用于执行带有FOR UPDATE SKIP LOCKED的查询,可通过QuerySet.select_for_update()使用。新增了
TEST['TEMPLATE']设置,允许 PostgreSQL 用户指定用于创建测试数据库的模板。QuerySet.iterator()现在在 PostgreSQL 上使用 server-side cursors。这个功能将一些用于保存查询结果的工作内存负载转移到数据库,可能会增加数据库的内存使用量。新增了对在
OPTIONS中使用'isolation_level'选项的 MySQL 支持,允许指定 事务隔离级别。为了避免可能的数据丢失,建议从 MySQL 的默认级别 repeatable read 切换到 read committed。新增了对
cx_Oracle5.3 的支持。
电子邮件¶
新增了
EMAIL_USE_LOCALTIME设置,允许将 SMTP 日期标头发送到本地时区,而不是 UTC。EmailMessage.attach()和attach_file()现在在为 text/* 附件指定无法解码为 UTF-8 的二进制内容时,会回退到 MIME 类型 application/octet-stream。
文件存储¶
为了能够被
io.TextIOWrapper包装,File现在具有readable()、writable()和seekable()方法。
表单¶
在
CharField、EmailField、RegexField、SlugField和URLField上新增了empty_value属性,允许指定表示 "空" 的 Python 值。新的
Form.get_initial_for_field()方法返回表单字段的初始数据。
国际化¶
数字格式化和
NUMBER_GROUPING设置支持非均匀的数字分组。
管理命令¶
新的
loaddata --exclude选项允许在从 fixture 加载数据时排除模型和应用程序。新的
diffsettings --default选项允许指定与 Django 默认设置进行比较的设置模块。app_label参数现在限制了showmigrations --plan输出。
迁移¶
新增了对
uuid.UUID对象的序列化支持。
模型¶
在
QuerySet.update_or_create()和get_or_create()的defaults参数中新增了对可调用值的支持。ImageField现在具有默认的validate_image_file_extension验证器。(此验证器在 Django 1.11.2 中移至表单字段。)Trunc函数现在支持时间截断。新增了
ExtractWeek函数,用于从DateField和DateTimeField中提取周,并通过week查询公开。新增了
TruncTime函数,用于将DateTimeField截断到其时间组件,并通过time查询公开。在
QuerySet.values()和values_list()中添加了对表达式的支持。对于接受多个参数的查询,如
range,新增了对查询表达式的支持。现在可以在
FileField上使用unique=True选项。新增了
Expression.asc()和desc()的nulls_first和nulls_last参数,用于控制空值的排序顺序。新的
F表达式中的bitleftshift()和bitrightshift()方法允许进行 位移位操作。新增了
QuerySet.union()、intersection()和difference()方法。
请求和响应¶
新增了
QueryDict.fromkeys()方法。CommonMiddleware现在为非流式响应设置Content-Length响应头。新增了
SECURE_HSTS_PRELOAD设置,允许将preload指令附加到Strict-Transport-Security头部。ConditionalGetMiddleware现在将ETag头部添加到响应中。
序列化¶
新的
django.core.serializers.base.Serializer.stream_class属性允许子类自定义默认流。可以通过向
serializers.serialize()函数传递一个cls关键字参数来自定义 JSON 序列化器 使用的编码器。DjangoJSONEncoder现在可以序列化timedelta对象(被DurationField使用)。
模板¶
现在可以将
mark_safe()用作装饰器。Jinja2模板后端现在支持通过在OPTIONS中设置'context_processors'选项来配置上下文处理器。regroup标签现在返回namedtuple而不是字典,因此你可以在循环中直接解包组对象,例如{% for grouper, list in regrouped %}。新增了
resetcycle模板标签,允许重置cycle模板标签的序列。现在可以为特定的
filesystem.Loader指定特定的目录。
测试¶
新增了
DiscoverRunner.get_test_runner_kwargs()方法,允许自定义传递给测试运行器的关键字参数。新增了
test --debug-mode选项,通过将DEBUG设置为True来帮助排查测试失败。新的
django.test.utils.setup_databases()(从django.test.runner移动过来)和teardown_databases()函数使构建自定义测试运行器更加容易。在使用
test --parallel选项时,新增了对unittest.TestCase.subTest()的支持。DiscoverRunner现在在测试运行开始时运行系统检查。如果要禁用此功能,请覆盖DiscoverRunner.run_checks()方法。
验证器¶
新增了
FileExtensionValidator以验证文件扩展名,以及validate_image_file_extension以验证图像文件。
1.11 中的向后不兼容更改¶
django.contrib.gis¶
为了简化代码库并且因为现在安装起来更容易(相对于最初发布
contrib.gis时的情况),现在在 GeoDjango 中需要 GDAL 作为依赖。在旧版本中,它只对 SQLite 有要求。contrib.gis.maps已被移除,因为它与已退役的 Google Maps API 版本进行交互,似乎没有维护。如果您正在使用它,请 告诉我们。GEOSGeometry的等号运算符现在也会比较 SRID。基于 OpenLayers 的表单小部件现在使用 OpenLayers 3,同时更新了
gis/openlayers.html和gis/openlayers-osm.html模板。如果您对这些小部件进行子类化或扩展模板,请检查您的项目。此外,新的小部件与旧的小部件有一些不同。不再使用小部件中的工具栏,而是点击以绘制,点击并拖动以移动地图,以及点击并拖动一个点/顶点/角来移动它。不再支持 SpatiaLite < 4.0 。
不再支持 GDAL 1.7 和 1.8 。
contrib.gis.forms.widgets中的小部件和管理员的OpenLayersWidget现在使用 表单渲染 API 而不是loader.render_to_string()。如果您使用自定义小部件模板,您需要确保您的表单渲染器可以找到它。例如,您可以使用TemplatesSetting渲染器。
django.contrib.staticfiles¶
当使用散列的静态文件存储时,如果存在引用循环(例如,
'foo.css'引用'bar.css',而'bar.css'又引用'foo.css'),或者如果引用其他文件的文件链过深,无法在多次传递中解析,那么collectstatic在后处理期间可能会失败。在后一种情况下,可以通过ManifestStaticFilesStorage.max_post_process_passes增加传递次数。当使用
ManifestStaticFilesStorage时,运行时未在清单中找到的静态文件现在会引发ValueError,而不是返回不变的路径。您可以通过将ManifestStaticFilesStorage.manifest_strict设置为False来恢复到旧的行为。
数据库后端 API¶
本节介绍了第三方数据库后端可能需要的更改。
新增了
DatabaseOperations.time_trunc_sql()方法,以支持TimeField截断。它接受一个lookup_type和field_name参数,并返回将给定时间字段field_name截断为只具有给定精度的时间对象的适当 SQL。lookup_type参数可以是'hour'、'minute'或'second'。新增了
DatabaseOperations.datetime_cast_time_sql()方法,以支持time查询。它接受一个field_name和tzname参数,并返回将日期时间值强制转换为时间值所需的 SQL。要启用
FOR UPDATE SKIP LOCKED支持,请设置DatabaseFeatures.has_select_for_update_skip_locked = True。新的
DatabaseFeatures.supports_index_column_ordering属性指定数据库是否允许在索引中定义列的排序。默认值为True,而DatabaseIntrospection.get_constraints()方法应在每个返回的字典中包含一个'orders'键,该键包含一个列表,其中包含与索引中每列的排序对应的'ASC'和/或'DESC'值。inspectdb不再调用已弃用的DatabaseIntrospection.get_indexes()方法。自定义数据库后端应确保DatabaseIntrospection.get_constraints()返回所有类型的索引。将
ignores_quoted_identifier_case功能的名称更改为ignores_table_name_case,以更准确地反映它的使用方式。新增了
name关键字参数到DatabaseWrapper.create_cursor(self, name=None)方法,以允许在支持的后端上使用服务器端游标。
不再支持 PostgreSQL 9.2 和 PostGIS 2.0 。¶
PostgreSQL 9.2 的上游支持将于 2017 年 9 月结束。因此,Django 1.11 将 PostgreSQL 9.3 设为其官方支持的最低版本。
由于 PostgreSQL 9.2 是支持 PostGIS 2.0 的最后一个版本,因此也取消了对 PostGIS 2.0 的支持。
此外,支持的最低 psycopg2 版本从 2.4.5 提高到 2.5.4 。
LiveServerTestCase 现在绑定到零端口¶
与其采用端口范围并迭代查找空闲端口,LiveServerTestCase 现在绑定到零端口,并依赖操作系统分配空闲端口。不再使用 DJANGO_LIVE_TEST_SERVER_ADDRESS 环境变量,也不再使用 manage.py test --liveserver 选项。
如果需要将 LiveServerTestCase 绑定到特定端口,可以使用 Django 1.11.2 中新增的 port 属性。
在 django.contrib.auth 和 i18n 视图中加强了对不安全的重定向的保护。¶
LoginView、LogoutView (以及已弃用的函数式等效版本)和 set_language() 在应用程序运行在 HTTPS 上时,会保护用户免受被重定向到非 HTTPS 的 next URL 的影响。
QuerySet.get_or_create() 和 update_or_create() 现在会验证参数。¶
为了防止拼写错误默默通过,get_or_create() 和 update_or_create() 检查它们的参数是否是模型字段。这只会在一个方面引入向后不兼容,可能会暴露出项目中的错误。
pytz 现在是必需的依赖项,不再支持将 settings.TIME_ZONE = None。¶
为了简化 Django 的时区处理,pytz 现在是必需的依赖项,它会自动与 Django 一起安装。
不再支持 settings.TIME_ZONE = None,因为这种行为通常不常用且可疑的有用性。如果希望根据系统时区自动检测时区,可以使用 tzlocal。
from tzlocal import get_localzone
TIME_ZONE = get_localzone().zone
这与 settings.TIME_ZONE = None 类似,但它还设置了 os.environ['TZ']。如果存在情况下,您发现无法适应设置 TIME_ZONE 的代码,请通过 告诉我们。
管理模板中的 HTML 更改¶
<p class="help"> 被替换为 <div> 标签,以允许在帮助文本中包含列表。
只读字段现在被包装在 <div class="readonly">...</div> 中,而不是 <p>...</p>,以允许字段内容包含任何类型的 HTML。
由于引入基于模板的小部件渲染,发生了一些更改。¶
移除了 django.forms.widgets 中一些未记录的类:
SubWidgetRendererMixin,ChoiceFieldRenderer,RadioFieldRenderer,CheckboxFieldRendererChoiceInput,RadioChoiceInput,CheckboxChoiceInput
移除了未记录的 Select.render_option() 方法。
移除了 Widget.format_output() 方法。请使用自定义小部件模板替代。
如果 settings.USE_L10N=True,现在某些小部件的值,如 <select> 选项,将进行本地化。您可以通过使用 localize 模板标签关闭本地化,恢复到旧的行为,使用自定义小部件模板。
django.template.backends.django.Template.render() 禁止非字典上下文。¶
为了与多个模板引擎兼容,django.template.backends.django.Template.render() (从高级模板加载器 API(如 loader.get_template())返回)必须接收一个上下文字典,而不是 Context 或 RequestContext。如果您之前传递了这两个类中的任何一个,请改为传递一个字典 - 这样做是向后兼容旧版本的 Django。
迁移操作中的模型状态更改¶
为了提高应用迁移的速度,延迟了相关模型的渲染,直到需要它们的操作(例如 RunPython)。如果您有一个自定义操作,需要在 database_forwards() 或 database_backwards() 的 from_state 参数中使用模型类或模型实例,您必须使用 clear_delayed_apps_cache() 方法来渲染模型状态,如 编写自己的迁移操作 中所述。
PostgreSQL 上的服务器端游标¶
将 QuerySet.iterator() 使用服务器端游标在 PostgreSQL 上可能会阻止在事务池模式下使用 PgBouncer 运行 Django。要重新允许这样做,可以在 DATABASES 中使用 DISABLE_SERVER_SIDE_CURSORS 设置(在 Django 1.11.1 中添加)。
有关更多讨论,请参阅 事务池和服务器端游标。
杂项¶
如果在 feed 中没有任何项目具有
pubdate或updateddate属性,那么SyndicationFeed.latest_post_date()现在会返回当前的 UTC 日期/时间,而不是一个没有任何时区信息的 datetime。CSRF 失败现在会被记录到
django.security.csrf日志器,而不是django.request。运行测试时,不再禁用
ALLOWED_HOSTS验证。如果您的应用程序包括具有自定义主机名的测试,您必须将这些主机名包含在ALLOWED_HOSTS中。请参阅 测试与多主机名。在
ModelAdmin.list_display中使用外键的 id(例如'field_id')会显示相关对象的 ID。如果要恢复到对象的字符串表示的旧行为,请移除_id后缀。在模型表单中,具有
null=True的CharField现在会为空白值保存NULL,而不是空字符串。在 Oracle 上,
Model.validate_unique()不再检查空字符串的唯一性,因为数据库会将该值解释为NULL。如果您子类化了
AbstractUser并覆盖了clean()方法,请确保它调用了super()。新的AbstractUser.clean()方法中会调用BaseUserManager.normalize_email(),以便在模型表单验证等情况下应用标准化。EmailField和URLField不再接受strip关键字参数。移除它,因为在旧版本的 Django 中它没有任何效果,这些字段总是会去除空格。表单小部件渲染的
checked和selected属性现在使用 HTML5 布尔语法,而不再使用 XHTML 的checked='checked'和selected='selected'。RelatedManager.add()、remove()、clear()和set()现在会清除prefetch_related()缓存。为防止可能丢失的保存设置,如果在调用
teardown_test_environment()之前再次调用setup_test_environment(),它现在会引发异常。未记录的
DateTimeAwareJSONEncoder别名(对于在 Django 1.0 中更名的DjangoJSONEncoder)已被移除。如果没有指定
OPTIONS['loaders']并且OPTIONS['debug']为False(后者默认为DEBUG的值),则现在会启用cached template loader。如果您有一些不是线程安全的 模板标签,这可能会导致不兼容。过去在运行
migrate命令之后不再提示删除陈旧的内容类型。现在请使用新的remove_stale_contenttypes命令。管理员界面中的
IntegerField控件现在使用type="number"而不是type="text"。patch_response_headers()不再添加Last-Modified标头。根据 RFC 7234 Section 4.2.2,在提供明确的过期时间的其他缓存标头旁边,例如Expires或Cache-Control,此标头是无用的。因此,UpdateCacheMiddleware和add_never_cache_headers()调用patch_response_headers(),因此也受到此更改的影响。在管理模板中,
<p class="help">被替换为<div>标签,以允许在帮助文本中包含列表。ConditionalGetMiddleware不再设置Date头,因为 web 服务器会设置该头。它也不再设置Content-Length头,因为现在由CommonMiddleware完成此操作。如果您有一个中间件在
MIDDLEWARE或MIDDLEWARE_CLASSES设置中出现在CommonMiddleware之前,并且修改响应的内容,那么您必须重新排列您的中间件,以确保在设置Content-Length后不会修改响应,或者让修改响应的中间件重置Content-Length头。get_model()和get_models()现在在所有应用程序的模型加载之前调用时会引发AppRegistryNotReady异常。以前它们只需要目标应用程序的模型被加载,因此可能返回未完全设置其关系的模型。如果您需要get_model()的旧行为,请将require_ready参数设置为False。未使用的
BaseCommand.can_import_settings属性已被删除。未记录的
django.utils.functional.lazy_property已被移除。为了与非多部分请求保持一致,
MultiPartParser.parse()现在会使request.POST保持不可变性。如果你要修改那个QueryDict,你现在必须先复制它,例如request.POST.copy()。对于
cx_Oracle版本小于 5.2 的支持已被移除。对于 IPython 版本小于 1.0 的支持已从
shell命令中移除。私有 API
Widget.build_attrs()的签名已从extra_attrs=None, **kwargs更改为base_attrs, extra_attrs=None。通过测试客户端上传到一个
ImageField的类似文件的对象(例如StringIO和BytesIO)现在需要一个具有通过validate_image_file_extension验证器的值的name属性。请参阅Client.post()中的注意事项。FileField现在会移动文件而不是复制它所接收的文件。使用默认的文件上传设置,文件大小超过FILE_UPLOAD_MAX_MEMORY_SIZE的文件现在具有与临时文件相同的权限(通常是0o600),而不是系统的标准掩码(通常是0o644)。如果您需要不考虑文件大小都具有相同权限,请设置FILE_UPLOAD_PERMISSIONS。
在 1.11 中被废弃的功能¶
models.permalink() 装饰器¶
请使用 django.urls.reverse()。例如:
from django.db import models
class MyModel(models.Model):
...
@models.permalink
def url(self):
return ("guitarist_detail", [self.slug])
变成:
from django.db import models
from django.urls import reverse
class MyModel(models.Model):
...
def url(self):
return reverse("guitarist_detail", args=[self.slug])
杂项¶
contrib.auth中的login()和logout()基于函数的视图已被弃用,推荐使用新的基于类的视图LoginView和LogoutView。contrib.auth.views.logout_then_login()的未使用的extra_context参数已被弃用。contrib.auth中的password_change(),password_change_done(),password_reset(),password_reset_done(),password_reset_confirm(), 和password_reset_complete()基于函数的视图已被弃用,推荐使用新的基于类的视图PasswordChangeView,PasswordChangeDoneView,PasswordResetView,PasswordResetDoneView,PasswordResetConfirmView, 和PasswordResetCompleteView。django.test.runner.setup_databases()已移至django.test.utils.setup_databases()。旧位置已被弃用。django.utils.translation.string_concat()已被弃用,推荐使用django.utils.text.format_lazy()。可以通过format_lazy('{}' * len(strings), *strings)来替代string_concat(*strings)。对于
PyLibMCCache缓存后端,将pylibmc行为设置作为OPTIONS的顶级属性传递已被弃用。请将它们设置在OPTIONS内的behaviors键下。django.utils.http.is_safe_url()的host参数已被弃用,推荐使用新的allowed_hosts参数。在渲染
{% include %}模板标签时抑制异常已被弃用,因为这种行为通常会比有帮助更令人困惑。在 Django 2.1 中,将会引发异常。DatabaseIntrospection.get_indexes()已被弃用,推荐使用DatabaseIntrospection.get_constraints()。authenticate()现在向身份验证后端的authenticate()方法传递一个request参数。不接受request作为第一个位置参数的方法将在 Django 2.1 中被移除。USE_ETAGS设置已被弃用,推荐使用ConditionalGetMiddleware,它现在会在响应中添加ETag头,不受设置的影响。当弃用结束时,CommonMiddleware和django.utils.cache.patch_response_headers()将不再设置 ETags。Model._meta.has_auto_field已被弃用,推荐检查Model._meta.auto_field is not None。在
url()中使用带有iLmsu#的正则表达式组已被弃用。唯一有用的组是(?i)用于不区分大小写的 URL,但是不区分大小写的 URL 并不是一个好的实践,因为它们会为搜索引擎创建多个条目,例如。一个替代方案可能是创建一个handler404,它查找 URL 中的大写字符并重定向到相应的小写字符。renderer参数已添加到Widget.render()方法。不接受该参数的方法将在一个弃用期内继续工作。