Dans certains cas, nous avons des problèmes lorsque certains de nos utilisateurs appellent l'API avec des terminaisons différentes. Habituellement, nos utilisateurs utilisent Postman pour cela et ne se préoccupent pas de la barre oblique à la fin. En conséquence, nous recevons des demandes de problème de support, car les utilisateurs ont oublié d'ajouter une barre oblique /
à la fin des requêtes POST.
Nous l'avons résolu en utilisant un middleware personnalisé qui fonctionne pour nous dans Django 3.2+ et Django 4.0+. Après cela, Django peut gérer toutes les requêtes POST/PUT/DELETE vers votre API avec ou sans barre oblique. Avec ce middleware, il n'est pas nécessaire de modifier la propriété APPEND_SLASH
dans settings.py
Donc, dans le settings.py
, il faut supprimer votre 'django.middleware.common.CommonMiddleware'
actuel et insérer un nouveau middleware. Assurez-vous de changer your_project_name
dans mon exemple ci-dessous par le nom réel de votre projet.
MIDDLEWARE = [
...
# 'django.middleware.common.CommonMiddleware',
'your_project_name.middleware.CommonMiddlewareAppendSlashWithoutRedirect',
...
]
Ajoutez au répertoire de votre application principale 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):
""" Cette classe convertit HttpSmartRedirectResponse en la réponse commune
de la vue Django, sans redirection. C'est nécessaire pour faire correspondre les codes d'état
pour les urls comme /url?q=1 et /url/?q=1. Si vous ne l'utilisez pas, vous aurez toujours le code 302
sur les pages sans barre oblique.
"""
response_redirect_class = HttpSmartRedirectResponse
def __init__(self, *args, **kwargs):
# créer un 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 get_full_path_with_slash(self, request):
""" Renvoie le chemin complet de la requête avec une barre oblique ajoutée à la fin
sans Exception en mode Debug
"""
new_path = request.get_full_path(force_append_slash=True)
# Empêcher la construction d'urls relatives au schéma.
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 + '/'
# nous n'avons pas besoin de 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
Cette réponse peut ressembler à la réponse de Max Tkachenko. Mais son code n'a pas fonctionné pour moi dans les dernières versions de Django.