Browse Source

Fix #12419: Update "Required, can be None" docs and fix example code

The documentation section "Required, can be None" incorrectly claimed that
a query parameter without a default value can accept None. In practice,
query parameters cannot send None via HTTP, and omitting a required
parameter results in a 422 error.

Changes:
- docs: Reword section to "Optional with None", clarify that = None
  makes the parameter optional (defaults to None)
- tutorial006c_an_py310.py: Add = None default
- tutorial006c_py310.py: Add default=None to Query()
- test_tutorial006c.py: Remove xfail markers, update expected
  required: True → False in OpenAPI schema
pull/15203/head
OscBot 4 months ago
parent
commit
a334ed9db4
  1. 12
      docs/en/docs/tutorial/query-params-str-validations.md
  2. 2
      docs_src/query_params_str_validations/tutorial006c_an_py310.py
  3. 2
      docs_src/query_params_str_validations/tutorial006c_py310.py
  4. 12
      tests/test_tutorial/test_query_params_str_validations/test_tutorial006c.py

12
docs/en/docs/tutorial/query-params-str-validations.md

@ -220,14 +220,20 @@ So, when you need to declare a value as required while using `Query`, you can si
{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *} {* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
### Required, can be `None` { #required-can-be-none } ### Optional with `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 is optional and can accept `None`, even when using `Query` for validations.
To do that, you can declare that `None` is a valid type but simply do not declare a default value: To do that, you can declare that `None` is a valid type and use `None` as the default value:
{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *} {* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
/// tip
This is the same as using `Query(None, min_length=3)`, the parameter is optional and will have a default value of `None`.
///
## Query parameter list / multiple values { #query-parameter-list-multiple-values } ## Query parameter list / multiple values { #query-parameter-list-multiple-values }
When you define a query parameter explicitly with `Query` you can also declare it to receive a list of values, or said in another way, to receive multiple values. When you define a query parameter explicitly with `Query` you can also declare it to receive a list of values, or said in another way, to receive multiple values.

2
docs_src/query_params_str_validations/tutorial006c_an_py310.py

@ -6,7 +6,7 @@ app = FastAPI()
@app.get("/items/") @app.get("/items/")
async def read_items(q: Annotated[str | None, Query(min_length=3)]): async def read_items(q: Annotated[str | None, Query(min_length=3)] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q: if q:
results.update({"q": q}) results.update({"q": q})

2
docs_src/query_params_str_validations/tutorial006c_py310.py

@ -4,7 +4,7 @@ app = FastAPI()
@app.get("/items/") @app.get("/items/")
async def read_items(q: str | None = Query(min_length=3)): async def read_items(q: str | None = Query(min_length=3, default=None)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q: if q:
results.update({"q": q}) results.update({"q": q})

12
tests/test_tutorial/test_query_params_str_validations/test_tutorial006c.py

@ -22,24 +22,18 @@ def get_client(request: pytest.FixtureRequest):
return client 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): def test_query_params_str_validations_no_query(client: TestClient):
response = client.get("/items/") response = client.get("/items/")
assert response.status_code == 200 assert response.status_code == 200
assert response.json() == { # pragma: no cover assert response.json() == {
"items": [{"item_id": "Foo"}, {"item_id": "Bar"}], "items": [{"item_id": "Foo"}, {"item_id": "Bar"}],
} }
@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): def test_query_params_str_validations_empty_str(client: TestClient):
response = client.get("/items/?q=") response = client.get("/items/?q=")
assert response.status_code == 200 assert response.status_code == 200
assert response.json() == { # pragma: no cover assert response.json() == {
"items": [{"item_id": "Foo"}, {"item_id": "Bar"}], "items": [{"item_id": "Foo"}, {"item_id": "Bar"}],
} }
@ -99,7 +93,7 @@ def test_openapi_schema(client: TestClient):
"operationId": "read_items_items__get", "operationId": "read_items_items__get",
"parameters": [ "parameters": [
{ {
"required": True, "required": False,
"schema": { "schema": {
"anyOf": [ "anyOf": [
{"type": "string", "minLength": 3}, {"type": "string", "minLength": 3},

Loading…
Cancel
Save