django urls without a trailing slash do not redirect

前端 未结 6 1787
不思量自难忘°
不思量自难忘° 2020-12-02 07:07

I\'ve got two applications located on two separate computers. On computer A, in the urls.py file I have a line like the following:

(r\'^cast/$\         


        
相关标签:
6条回答
  • 2020-12-02 07:27

    I've had the same problem. In my case it was a stale leftover from some old version in urls.py, from before staticfiles:

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

    MEDIA_URL was empty, so this pattern matched everything.

    0 讨论(0)
  • 2020-12-02 07:32

    Append slash without redirect, use it instead of CommonMiddleware in settings, Django 2.1:

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

    Add to your main app directory 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
    
    0 讨论(0)
  • 2020-12-02 07:36

    This improves on @Michael Gendin's answer. His answer serves the identical page with two separate URLs. It would be better to have login automatically redirect to login/, and then serve the latter as the main page:

    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"),
    )
    
    0 讨论(0)
  • 2020-12-02 07:37

    I've had the same problem too. My solution was put an (|/) before the end line of my regular expression.

    url(r'^artists/(?P[\d]+)(|/)$', ArtistDetailView.as_view()),

    0 讨论(0)
  • 2020-12-02 07:44

    check your APPEND_SLASH setting in the settings.py file

    more info in the django docs

    0 讨论(0)
  • 2020-12-02 07:46

    Or you can write your urls like this:

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

    The question sign after the trailing slash makes it optional in regexp. Use it if for some reasons you don't want to use APPEND_SLASH setting.

    0 讨论(0)
提交回复
热议问题