From 58afccb27518c739afe09f6c2b32a88c1aa20c47 Mon Sep 17 00:00:00 2001 From: r266-tech <186549687+r266-tech@users.noreply.github.com> Date: Mon, 23 Mar 2026 03:12:23 +0800 Subject: [PATCH] Fix: clarify 'Required, can be None' query parameter docs The documentation incorrectly stated that clients could send None as a query parameter value. In reality, omitting a required parameter returns 422, and there is no standard HTTP mechanism to pass None as a query string value. Changes: - Updated docs to clarify that None in the type annotation means the OpenAPI schema marks the parameter as nullable - Added info box explaining the actual behavior - Fixed xfail tests to verify correct 422 behavior instead of expecting impossible 200 responses Closes #12419 --- .../tutorial/query-params-str-validations.md | 8 ++++- .../test_tutorial006c.py | 35 ++++++++++++------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/docs/en/docs/tutorial/query-params-str-validations.md b/docs/en/docs/tutorial/query-params-str-validations.md index 4765b36cbe..8dfd2503e4 100644 --- a/docs/en/docs/tutorial/query-params-str-validations.md +++ b/docs/en/docs/tutorial/query-params-str-validations.md @@ -222,10 +222,16 @@ So, when you need to declare a value as required while using `Query`, you can si ### Required, can be `None` { #required-can-be-none } -You can declare that a parameter can accept `None`, but that it's still required. This would force clients to send a value, even if the value is `None`. +You can declare that a parameter's type can be `None`, but that it's still **required** (it must be included in the request). This is useful when you want to require the parameter to be present, but allow the value to be `None`. To do that, you can declare that `None` is a valid type but simply do not declare a default value: +/// info + +When the parameter is required (no default value), omitting it will result in a **422 Validation Error**. The `None` type is included so that the OpenAPI schema correctly represents the parameter as **nullable**, and it allows your code to handle a `None` value explicitly. However, note that there's no standard HTTP mechanism to send `None` as a query parameter value from a client. + +/// + {* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *} ## Query parameter list / multiple values { #query-parameter-list-multiple-values } diff --git a/tests/test_tutorial/test_query_params_str_validations/test_tutorial006c.py b/tests/test_tutorial/test_query_params_str_validations/test_tutorial006c.py index 74c10b885d..23f5c9f9c2 100644 --- a/tests/test_tutorial/test_query_params_str_validations/test_tutorial006c.py +++ b/tests/test_tutorial/test_query_params_str_validations/test_tutorial006c.py @@ -22,25 +22,36 @@ def get_client(request: pytest.FixtureRequest): return client -@pytest.mark.xfail( - reason="Code example is not valid. See https://github.com/fastapi/fastapi/issues/12419" -) def test_query_params_str_validations_no_query(client: TestClient): + """When q is required (no default), omitting it returns 422.""" response = client.get("/items/") - assert response.status_code == 200 - assert response.json() == { # pragma: no cover - "items": [{"item_id": "Foo"}, {"item_id": "Bar"}], + assert response.status_code == 422 + assert response.json() == { + "detail": [ + { + "type": "missing", + "loc": ["query", "q"], + "msg": "Field required", + "input": None, + } + ] } -@pytest.mark.xfail( - reason="Code example is not valid. See https://github.com/fastapi/fastapi/issues/12419" -) def test_query_params_str_validations_empty_str(client: TestClient): + """Empty string fails min_length validation.""" response = client.get("/items/?q=") - assert response.status_code == 200 - assert response.json() == { # pragma: no cover - "items": [{"item_id": "Foo"}, {"item_id": "Bar"}], + assert response.status_code == 422 + assert response.json() == { + "detail": [ + { + "type": "string_too_short", + "loc": ["query", "q"], + "msg": "String should have at least 3 characters", + "input": "", + "ctx": {"min_length": 3}, + } + ] }