diff --git a/redirects/middleware.py b/redirects/middleware.py index 8f957d1af..7e8546b72 100644 --- a/redirects/middleware.py +++ b/redirects/middleware.py @@ -1,3 +1,4 @@ +from django.db.models import CharField, F, Value from django.db.models.functions import Length from django.shortcuts import redirect @@ -27,11 +28,11 @@ def __call__(self, request): # look for a direct or prefix match on the current URL redirection = ( - Redirect.objects.extra( - where=["%s LIKE concat(old_url, '%%')"], - params=[request.path], + Redirect.objects.annotate( + url_length=Length("old_url"), + request_url=Value(request.path, output_field=CharField()), ) - .annotate(url_length=Length("old_url")) + .filter(request_url__startswith=F("old_url")) .order_by("-url_length") .first() ) diff --git a/tests/unit/redirects/test_middleware.py b/tests/unit/redirects/test_middleware.py index ebd0faf7f..c6edf6520 100644 --- a/tests/unit/redirects/test_middleware.py +++ b/tests/unit/redirects/test_middleware.py @@ -39,3 +39,16 @@ def test_redirectsmiddleware_unknown_url(rf): response = RedirectsMiddleware(get_response)(request) assert response == "no match" + + +def test_redirect_with_wildcard_in_path(rf): + w1 = WorkspaceFactory() + w2 = WorkspaceFactory() + RedirectFactory(old_url="/abc/123/test_workspace/", workspace=w1) + RedirectFactory(old_url="/abc/123/test-workspace/", workspace=w2) + + request = rf.get("/abc/123/test-workspace/") + + response = RedirectsMiddleware(get_response)(request) + + assert response.url == w2.get_absolute_url()