升级到 Django 1.11 后 append_slash 不再起作用

Posted

技术标签:

【中文标题】升级到 Django 1.11 后 append_slash 不再起作用【英文标题】:After upgrade to Django 1.11 append_slash no longer works 【发布时间】:2018-03-11 20:59:29 【问题描述】:

在 Django 1.9(和 Python 3.4)中,默认的 APPEND_SLASH 工作正常,即我可以输入 'localhost:8000/ideatree/videos' 并且会添加尾部斜杠。

升级到 Django 1.11(和 Python 3.6)后,APPEND_SLASH 不再工作。

我已经查找了弃用通知,但到目前为止没有发现任何似乎适用的内容。 (附带问题:您如何重新打开“大声弃用警告”,就像在以前的版本中一样?)

这是我的主要 urls.py:

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [   url(r'^(?i)ideatree/', include('ideatree.urls'),
 name='home'),
]

以及包含的 app_space 中的 urls.py:

from django.conf.urls import url
from . import views

app_name = 'ideatree'
urlpatterns = [
   url(r'^$', views.index,name='index'),
   url(r'^(?i)features/$', views.features, name='features'),
   url(r'^(?i)videos/$', views.videos, name='videos')
]

这两个 url.py 文件都没有改变,除了在 Django 1.9 中我有

from django.conf.urls import patterns, include, url

在主 urls.py 中,但现在不推荐使用“模式”并引发警告。

和以前一样,我没有在 settings.py 中设置 APPEND_SLASH,依赖于其默认值 True,尽管我尝试将其显式设置为 True,但结果相同。

这是我的中间件:

MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

这是错误:

Page not found (404)
Request Method: GET
Request URL:    http://localhost:8000/ideatree/videos

Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^(?i)ideatree/ ^$ [name='index']
^(?i)ideatree/ ^(?i)features/$ [name='features']
^(?i)ideatree/ videos/$ [name='videos']

我还尝试清除浏览器缓存,并使用其他浏览器以防缓存仍未清除。

在 DEBUG 或 INFO 级别记录到文件不显示任何内容,一个空文件(警告:我的日志记录设置未经测试)。

一定有什么我忽略了。

【问题讨论】:

如果您从主 URL 和应用 URL 的正则表达式中删除 (?i),重定向是否有效? 它不适用于从两个 url 的正则表达式中删除的 (?i)。我还删除了 app_name 以防万一。结果相同。 令我惊讶的是,错误消息中的模式并非始终包含^(?i)。您是否发布了您的确切代码和错误消息? 你的设置中有MIDDLEWARE吗(在 Django 1.10 中添加)? 啊,是的。我必须使用 Django 1.9 中间件。它在 1) 将 MIDDLEWARE_CLASSES 更改为 MIDDLEWARE,2) 根据 Stack Overflow***.com/questions/40876355/… 导入 MiddlewareMixin 和 3) 删除 SessionAuthenticationMiddleware 后起作用,因为它不再出现在 Django 1.10 文档中。我必须仔细阅读文档以确保中间件功能仍然完整。 @Alasdair 您可以发布答案以便我接受吗?非常感谢,如果没有您的帮助,永远不会找到这个。 【参考方案1】:

Django 在 Django 1.10 中引入了新的中间件。如果您使用的是new-style middleware,则应使用MIDDLEWARE 设置,如果您使用的是old-style middleware,则应使用MIDDLEWARE_CLASSES

如果您使用的是 Django 1.10 或 1.11,那么旧的 MIDDLEWARE_CLASSES 设置仍然受支持,因此 Django 应继续使用附加的斜杠进行重定向。

但是,一旦升级到 Django 2.0,MIDDLEWARE_CLASSES 设置将被忽略,您必须切换到 MIDDLEWARE

当你切换到MIDDLEWARE 时,你应该删除SessionAuthenticationMiddleware,因为它在 1.10 和 1.11 中没有效果,并且在 Django 2.0 中被完全删除。

【讨论】:

也许这也是 MIDDLEWARE_CLASSES 和 SessionAuthenticationMiddleware 类之间的交互,它们没有出现在 Django 1.11 文档中,因为直到它们被删除才起作用? 不,SessionAuthenticationMiddleware 不会造成任何问题。在 Django 1.11 中,出于向后兼容性的原因,它是一个存根类。它没有任何效果,但您不必将其从 MIDDLEWARE_CLASSES 中删除。 如果我不注释掉我的 SessionAuthenticationMiddleware 我得到“ImportError:模块“django.contrib.auth.middleware”没有定义“SessionAuthenticationMiddleware”属性/类”。我使用的中间件是直接来自文档docs.djangoproject.com/en/1.11/topics/http/middleware/… 的列表。 如果在MIDDLEWARE_CLASSES 中包含SessionAuthenticationMiddleware - 中间件still exists in Django 1.11,则不会出现该错误。如果您不需要与其他版本的 Django 向后兼容,那么最好将其删除。我的意思是SessionAuthenticationMiddleware 没有解释你原来的问题。 是的,只要我不使用 SessionAuthenticationMiddleware,add_slash 现在即使不导入 MiddlewareMixin 也可以将中间件从 1.9 更新到 1.11 样式。还有其他事情发生。我怀疑你之前提到的 (?i) 正则表达式有什么问题。

以上是关于升级到 Django 1.11 后 append_slash 不再起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 1.11 中运行 celery worker

django 1.11 与 celery 4.0 和 djcelery 兼容性问题

在 Django 1.11 中将 QuerySet 传递给 Celery 任务

Django 1.6 到 1.11 Admin.py 迁移

如何在 django 1.11 中查找给定月份每周的记录数?

Django 1.11 模型迁移操作不适用