Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add query params to redirect response #3901

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions litestar/response/redirect.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from __future__ import annotations

import itertools
from typing import TYPE_CHECKING, Any, Iterable, Literal
from typing import TYPE_CHECKING, Any, Iterable, Literal, Sequence
from urllib.parse import urlencode

from litestar.constants import REDIRECT_ALLOWED_MEDIA_TYPES, REDIRECT_STATUS_CODES
from litestar.enums import MediaType
Expand All @@ -13,6 +14,8 @@
from litestar.utils.helpers import get_enum_string_value

if TYPE_CHECKING:
from collections.abc import Mapping

from litestar.app import Litestar
from litestar.background_tasks import BackgroundTask, BackgroundTasks
from litestar.connection import Request
Expand Down Expand Up @@ -94,6 +97,7 @@ def __init__(
media_type: str | MediaType | None = None,
status_code: RedirectStatusType | None = None,
type_encoders: TypeEncodersMap | None = None,
query_params: Mapping[str, str | Sequence[str]] | None = None,
marcuslimdw marked this conversation as resolved.
Show resolved Hide resolved
) -> None:
"""Initialize the response.

Expand All @@ -108,12 +112,16 @@ def __init__(
status_code: An HTTP status code. The status code should be one of 301, 302, 303, 307 or 308,
otherwise an exception will be raised.
type_encoders: A mapping of types to callables that transform them into types supported for serialization.
query_params: A dictionary of values from which the request's query will be generated.

Raises:
ImproperlyConfiguredException: Either if status code is not a redirect status code or media type is not
supported.
"""
self.url = path
if query_params is None:
self.url = path
else:
self.url = f"{path}?{urlencode(query_params, doseq=True)}"
if status_code is None:
status_code = HTTP_302_FOUND
super().__init__(
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/test_response/test_redirect_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ def handler() -> Redirect:
assert res.status_code == expected_status_code


def test_redirect_with_query_params() -> None:
@get("/")
def handler() -> Redirect:
return Redirect(path="/something-else", query_params={"single": "a", "list": ["b", "c"]})

with create_test_client([handler]) as client:
location_header = client.get("/", follow_redirects=False).headers["location"]
expected = "/something-else?single=a&list=b&list=c"
assert location_header == expected


@pytest.mark.parametrize("handler_status_code", [301, 307, None])
def test_redirect(handler_status_code: Optional[int]) -> None:
@get("/", status_code=handler_status_code)
Expand Down
Loading