django URL没有一个尾随的斜杠不重定向

mgdq6dx1  于 2023-07-01  发布在  Go
关注(0)|答案(8)|浏览(118)

我在两台不同的电脑上安装了两个应用程序。在计算机A上,在urls.py文件中,我有一行如下所示:

(r'^cast/$', 'mySite.simulate.views.cast')

这个url对mySite.com/cast/mySite.com/cast都有效。但是在计算机B上,我有一个类似的URL,如下所示:

(r'^login/$', 'mySite.myUser.views.login')

由于某些原因,在计算机B上,url mySite.com/login/将工作,但mySite.com/login将挂起,并且不会像在计算机A上那样直接返回到mySite.com/login/。我是不是错过了什么?两个url.py文件看起来完全相同。

frebpwbc

frebpwbc1#

或者你可以这样写你的URL:

(r'^login/?$', 'mySite.myUser.views.login')

尾部斜杠后面的问号使其在regexp中是可选的。如果出于某些原因不想使用APPEND_SLASH设置,请使用它。

6bc51xsx

6bc51xsx2#

检查www.example.com文件中的APPEND_SLASH设置settings.py
更多信息在django文档中

2cmtqfgy

2cmtqfgy3#

这比@Michael Gendin的回答更好。他的答案提供了两个独立的URL的相同页面。最好让login自动重定向到login/,然后将后者作为主页:

from django.conf.urls import patterns
from django.views.generic import RedirectView

urlpatterns = patterns('',
    # Redirect login to login/
    (r'^login$', RedirectView.as_view(url = '/login/')),
    # Handle the page with the slash.
    (r'^login/', "views.my_handler"),
)
ux6nzvsh

ux6nzvsh4#

我也有同样的问题。我的答案是(|/)在我的正则表达式的结束行之前。
url(r'^artists/(?P[\d]+)(|/)$', ArtistDetailView.as_view()),

disho6za

disho6za5#

追加斜杠不带重定向,在设置中使用它代替CommonMiddleware,Django 2.1:

MIDDLEWARE = [
    ...
    # 'django.middleware.common.CommonMiddleware',
    'htx.middleware.CommonMiddlewareAppendSlashWithoutRedirect',
    ...
]

添加到您的主应用程序目录 middleware.py

from django.http import HttpResponsePermanentRedirect, HttpRequest
from django.core.handlers.base import BaseHandler
from django.middleware.common import CommonMiddleware
from django.conf import settings

class HttpSmartRedirectResponse(HttpResponsePermanentRedirect):
    pass

class CommonMiddlewareAppendSlashWithoutRedirect(CommonMiddleware):
    """ This class converts HttpSmartRedirectResponse to the common response
        of Django view, without redirect.
    """
    response_redirect_class = HttpSmartRedirectResponse

    def __init__(self, *args, **kwargs):
        # create django request resolver
        self.handler = BaseHandler()

        # prevent recursive includes
        old = settings.MIDDLEWARE
        name = self.__module__ + '.' + self.__class__.__name__
        settings.MIDDLEWARE = [i for i in settings.MIDDLEWARE if i != name]

        self.handler.load_middleware()

        settings.MIDDLEWARE = old
        super(CommonMiddlewareAppendSlashWithoutRedirect, self).__init__(*args, **kwargs)

    def process_response(self, request, response):
        response = super(CommonMiddlewareAppendSlashWithoutRedirect, self).process_response(request, response)

        if isinstance(response, HttpSmartRedirectResponse):
            if not request.path.endswith('/'):
                request.path = request.path + '/'
            # we don't need query string in path_info because it's in request.GET already
            request.path_info = request.path
            response = self.handler.get_response(request)

        return response
brqmpdu1

brqmpdu16#

在某些情况下,当我们的一些用户调用具有不同结尾的API时,我们会遇到问题。通常,我们的用户使用Postman,并不担心端点处的斜杠。结果,我们在支持中收到了问题请求,因为用户忘记在POST请求的末尾附加斜杠/
我们通过使用自定义中间件解决了这个问题,该中间件适用于Django 3.2+Django 4.0+。在此之后,Django可以处理任何POST/PUT/DELETE请求到您的API,使用或不使用斜杠。使用此中间件,无需在www.example.com中更改APPEND_SLASH属性settings.py
因此,在settings.py中需要删除当前的'django.middleware.common.CommonMiddleware'并插入新的中间件。请确保在下面的示例中更改了真实的项目名称上的your_project_name

MIDDLEWARE = [
...
  # 'django.middleware.common.CommonMiddleware',
    'your_project_name.middleware.CommonMiddlewareAppendSlashWithoutRedirect',
...
]

添加到您的主应用程序目录middleware.py:

from django.http import HttpResponsePermanentRedirect, HttpRequest
from django.core.handlers.base import BaseHandler
from django.middleware.common import CommonMiddleware
from django.utils.http import escape_leading_slashes
from django.conf import settings

class HttpSmartRedirectResponse(HttpResponsePermanentRedirect):
    pass

class CommonMiddlewareAppendSlashWithoutRedirect(CommonMiddleware):
    """ This class converts HttpSmartRedirectResponse to the common response
            of Django view, without redirect. This is necessary to match status_codes
            for urls like /url?q=1 and /url/?q=1. If you don't use it, you will have 302
            code always on pages without slash.
    """
    response_redirect_class = HttpSmartRedirectResponse

def __init__(self, *args, **kwargs):
    # create django request resolver
    self.handler = BaseHandler()

    # prevent recursive includes
    old = settings.MIDDLEWARE
    name = self.__module__ + '.' + self.__class__.__name__
    settings.MIDDLEWARE = [i for i in settings.MIDDLEWARE if i != name]

    self.handler.load_middleware()

    settings.MIDDLEWARE = old
    super(CommonMiddlewareAppendSlashWithoutRedirect, self).__init__(*args, **kwargs)

def get_full_path_with_slash(self, request):
    """ Return the full path of the request with a trailing slash appended
        without Exception in Debug mode
    """
    new_path = request.get_full_path(force_append_slash=True)
    # Prevent construction of scheme relative urls.
    new_path = escape_leading_slashes(new_path)
    return new_path

def process_response(self, request, response):
    response = super(CommonMiddlewareAppendSlashWithoutRedirect, self).process_response(request, response)

    if isinstance(response, HttpSmartRedirectResponse):
        if not request.path.endswith('/'):
            request.path = request.path + '/'
        # we don't need query string in path_info because it's in request.GET already
        request.path_info = request.path
        response = self.handler.get_response(request)

    return response

这个答案可能看起来类似于马克斯·特卡琴科的答案。但是他的代码在最新版本的Django中对我不起作用。

nle07wnf

nle07wnf7#

我也遇到过同样的问题。在我的例子中,它是从www.example.com中的一些旧版本中遗留urls.py,来自staticfiles之前:

url(r'^%s(?P<path>.*)$' % settings.MEDIA_URL.lstrip('/'),
    'django.views.static.serve',
    kwargs={'document_root': settings.MEDIA_ROOT}),

MEDIA_URL为空,因此此模式匹配所有内容。

zte4gxcn

zte4gxcn8#

在Django项目的设置文件(settings.py)中,确保APPEND_SLASH设置为True:

APPEND_SLASH = True

接下来,将CommonMiddleware添加到MIDDLEWARE设置中:

MIDDLEWARE = [
    # other middleware classes...
    'django.middleware.common.CommonMiddleware',
    # other middleware classes...
]

使用此配置,Django的CommonMiddleware将自动处理URL重定向,并根据需要添加或删除尾部斜杠。这意味着对'xyz/'和'xyz'的请求将被Django REST框架正确处理。

**注意-**请求时,一般建议在尾部加上斜杠,以符合RESTful规范。但是,使用上述配置,没有尾随斜杠的请求仍将按预期工作。

相关问题