Django 禁用斜杠

Posted

技术标签:

【中文标题】Django 禁用斜杠【英文标题】:Django disable trailing slash 【发布时间】:2018-12-10 03:39:44 【问题描述】:

我正在使用 Django 2.0.6(目前使用开发服务器)并且遇到了自动将斜杠附加到 URL 的问题。

我的目标是有一个如下的 URL 结构:

/teams/ => 所有团队的索引视图 /teams/create => 用于创建新团队的表单视图(注意缺少尾部斜杠) /teams/xyz/ => 带有 slug xyz 的团队的索引视图 /teams/xyz/delete => 用于删除团队 xyz 的表单视图(需要确认等)

问题在于,在 Django 框架中的某个地方,尾部斜杠会自动附加到“创建”URL。因此,路由器会尝试使用 slug 'create' 为团队加载团队索引页面。显然,一种解决方法是停止使用 slug 并使用 ID,但这似乎是不必要的让步。

环顾四周,似乎将 APPEND_SLASH 设置为 False 应该告诉 CommonMiddleware 停止附加斜杠,但这没有帮助。

有没有一种方法可以轻松完成我的 URL 方案,如果没有,Django 的惯用方法是什么?

urls.py:

from django.urls import path

urlpatterns = [
    path('create', views.create, name='create'),
    path('<slug:team_slug>/', views.view, name='view'),
    path('<slug:team_slug>/invite/', views.invite, name='invite')
]

settings.py:

APPEND_SLASH = False

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

使用以下内容正确生成链接:

<a class="btn btn-primary" href="% url 'teams:create' %">New Team</a>

翻译为:/teams/create

但是,当用户点击链接时,它似乎立即被重定向到/teams/create/

【问题讨论】:

您能否澄清一下,是正在生成一个包含额外斜杠的链接,还是您输入了无斜杠的 URL 并且您被重定向到带有斜杠的链接?如果是前者,您能否展示一个包含链接的模板示例? @DanielRoseman :在我的模板代码中没有斜杠的情况下,该链接是正确生成的,但是当您点击该链接时,您会立即被重定向到带有斜杠的相同 URL。到达那里后,如果您从 URL 中删除斜杠并手动转到该页面,您将再次被重定向。我已经更新了问题。 奇怪的是,即使 APPEND_SLASH 为 True,CommonMiddleware 也只会在没有斜杠没有匹配的情况下重定向。所以它一定是别的东西。 【参考方案1】: 在您的项目目录中创建一个名为common 的目录。

common 目录中创建__init__.pyredirect.py

# redirect.py

from django.conf import settings
from django.core import urlresolvers
from django import http

'''
Based on django/middleware/common.py

Django convention is to add trailing slashes to most urls
This method does the opposite and redirects trailing slashes to the
no trailing slash url if it exists
'''
class RedirectTrailingSlashMiddleware(object):

    def process_request(self, request):
        if settings.APPEND_SLASH:
            return 

    if '/admin' in request.path:
        settings.APPEND_SLASH = True         
        return

    new_url = old_url = request.path

    if (old_url.endswith('/')):
        urlconf = getattr(request, 'urlconf', None)
        if (not urlresolvers.is_valid_path(request.path_info, urlconf) and
            urlresolvers.is_valid_path(request.path_info[:-1], urlconf)):
            new_url = new_url[:-1]
            if settings.DEBUG and request.method == 'POST':
                raise RuntimeError((""
                "You called this URL via POST, but the URL ends "
                "in a slash and you have APPEND_SLASH set. Django can't "
                "redirect to the non-slash URL while maintaining POST data. "
                "Change your form to point to %s (note no trailing "
                "slash), or set APPEND_SLASH=True in your Django "
                "settings.") % (new_url))

    if new_url == old_url:
        # No redirects required.
        return

    return http.HttpResponsePermanentRedirect(new_url)

在您的settings.py 中,添加:

MIDDLEWARE = [
    'common.redirect.RedirectTrailingSlashMiddleware',
    # Add as first element
]

来源/信用:http://bunwich.blogspot.com/2013/06/django-change-trailing-slash-url.html

【讨论】:

以上是关于Django 禁用斜杠的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用 301 重定向,在 Apache 中将斜杠添加到目录名称

choiceField的“禁用”选项 - Django

在 Django 中禁用会话创建

Django学习之禁用csrf和使用csrf操作详解

Django/Django Rest 框架 - 禁用 CSRF

css cursor(鼠标悬浮禁用)