Ответ 1
проверьте настройки APPEND_SLASH
в файле settings.py
У меня есть два приложения, расположенные на двух отдельных компьютерах. На компьютере 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
будет висеть и не вернется обратно к mySite.com/login/
, как на компьютере A. Я что-то пропустил? Оба файла url.py
выглядят идентично мне.
проверьте настройки APPEND_SLASH
в файле settings.py
Или вы можете написать свои URL-адреса следующим образом:
(r'^login/?$', 'mySite.myUser.views.login')
Знак вопроса после конечной косой черты делает его необязательным в regexp. Используйте его, если по каким-то причинам вы не хотите использовать параметр APPEND_SLASH.
Это улучшает ответ @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"),
)
У меня тоже была проблема. Мое решение было помещено (|/) до конечной строки моего регулярного выражения.
url(r'^artists/(?P[\d]+)(|/)$', ArtistDetailView.as_view()),
У меня была такая же проблема. В моем случае это была устаревшая остаточная часть старой версии в urls.py, начиная с staticfiles:
url(r'^%s(?P<path>.*)$' % settings.MEDIA_URL.lstrip('/'),
'django.views.static.serve',
kwargs={'document_root': settings.MEDIA_ROOT}),
MEDIA_URL был пуст, поэтому этот шаблон соответствовал всем.
Добавьте слеш без перенаправления, используйте его вместо 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 in request.GET already
request.path_info = request.path
response = self.handler.get_response(request)
return response