diff --git a/ninja/signature/details.py b/ninja/signature/details.py index 6eec55387..c9b2d1bd8 100644 --- a/ninja/signature/details.py +++ b/ninja/signature/details.py @@ -25,6 +25,10 @@ class ViewSignature: + FLATTEN_PATH_SEP = ( + "\x1e" # ASCII Record Separator. IE: not generally used in query names + ) + def __init__(self, path: str, view_func: Callable) -> None: self.view_func = view_func self.signature = get_typed_signature(self.view_func) @@ -157,7 +161,7 @@ def _args_flatten_map(self, args: List[FuncParam]) -> Dict[str, Tuple[str, ...]] raise ConfigError( f"Duplicated name: '{name}' in params: '{arg_names[name]}' & '{arg.name}'" ) - flatten_map[name] = tuple(path.split(".")) + flatten_map[name] = tuple(path.split(self.FLATTEN_PATH_SEP)) arg_names[name] = arg.name else: name = arg.alias @@ -173,7 +177,7 @@ def _args_flatten_map(self, args: List[FuncParam]) -> Dict[str, Tuple[str, ...]] def _model_flatten_map(self, model: TModel, prefix: str) -> Generator: for field in model.__fields__.values(): field_name = field.alias - name = f"{prefix}.{field_name}" + name = f"{prefix}{self.FLATTEN_PATH_SEP}{field_name}" if is_pydantic_model(field.type_): yield from self._model_flatten_map(field.type_, name) else: diff --git a/tests/main.py b/tests/main.py index 63e2540cd..20a9cdb4c 100644 --- a/tests/main.py +++ b/tests/main.py @@ -2,7 +2,7 @@ from django.urls import register_converter -from ninja import Path, Query, Router +from ninja import Field, Path, Query, Router, Schema router = Router() @@ -225,6 +225,15 @@ def get_query_param_required_type(request, query: int = Query(...)): return f"foo bar {query}" +class AliasedSchema(Schema): + query: str = Field(..., alias="aliased.-_~name") + + +@router.get("/query/aliased-name") +def get_query_aliased_name(request, query: AliasedSchema = Query(...)): + return f"foo bar {query.query}" + + class CustomPathConverter1: regex = "[0-9]+" diff --git a/tests/test_query.py b/tests/test_query.py index b4f91e47d..d3f1f3079 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -54,6 +54,7 @@ ("/query/param-required/int", 422, response_missing), ("/query/param-required/int?query=50", 200, "foo bar 50"), ("/query/param-required/int?query=foo", 422, response_not_valid_int), + ("/query/aliased-name?aliased.-_~name=foo", 200, "foo bar foo"), ], ) def test_get_path(path, expected_status, expected_response):