107 votes

Les URL Django sans barre oblique finale ne redirigent pas

J'ai deux applications situées sur deux ordinateurs distincts. Sur l'ordinateur A, dans le fichier urls.py , j'ai une ligne comme celle-ci:

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

Et cette URL fonctionnera à la fois pour mySite.com/cast/ et mySite.com/cast . Mais sur l'ordinateur B, j'ai une URL similaire écrite comme suit:

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

Pour une raison quelconque, sur l'ordinateur B, l'URL mySite.com/login fonctionnera mais mySite.com/login va bloquer et ne redirigera pas vers mySite.com/login/ comme sur l'ordinateur A. Est-ce que j'ai manqué quelque chose? Les fichiers urls.py me semblent identiques.

223voto

Michael Gendin Points 893

Ou vous pouvez écrire vos URL de cette manière :

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

Le point d'interrogation après le slash final le rend optionnel en regexp. Utilisez-le si, pour une raison quelconque, vous ne voulez pas utiliser le paramètre APPEND_SLASH.

122voto

Jiaaro Points 14379

Vérifiez votre paramètre APPEND_SLASH dans le fichier settings.py

plus d'informations dans la documentation de django

23voto

speedplane Points 3828

Cela améliore la réponse de @Michael Gendin. Sa réponse sert la même page avec deux URL distincts. Il serait préférable d'avoir login redirigé automatiquement vers login/, puis de servir ce dernier comme page principale :

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

urlpatterns = patterns('',
    # Rediriger login vers login/
    (r'^login$', RedirectView.as_view(url = '/login/')),
    # Gérer la page avec le slash.
    (r'^login/', "views.my_handler"),
)

3voto

J'ai eu le même problème aussi. Ma solution a été de mettre un (|/) avant la fin de la ligne de mon expression régulière.

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

2voto

Max Tkachenko Points 340

Ajoutez une barre oblique sans redirection, utilisez-la à la place de CommonMiddleware dans les paramètres, Django 2.1 :

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

Ajoutez à votre répertoire principal de l'application 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):
    """Cette classe convertit HttpSmartRedirectResponse en la réponse commune de la vue Django, sans redirection."""
    response_redirect_class = HttpSmartRedirectResponse

    def __init__(self, *args, **kwargs):
        # créer le résolveur de requête Django
        self.handler = BaseHandler()

        # empêcher les inclusions récursives
        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 + '/'
            # nous n'avons pas besoin de la chaîne de requête dans path_info car elle est déjà dans request.GET
            request.path_info = request.path
            response = self.handler.get_response(request)

        return response

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X