From d91a1d7a94b949a02f38f08bef7b99eb594be9a5 Mon Sep 17 00:00:00 2001 From: lotte-amsterdam Date: Thu, 21 May 2026 16:33:53 +0200 Subject: [PATCH 1/2] added exception for array of objects field filter --- src/dso_api/dynamic_api/filters/parser.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/dso_api/dynamic_api/filters/parser.py b/src/dso_api/dynamic_api/filters/parser.py index f8ed7c0d5..76a2c9599 100644 --- a/src/dso_api/dynamic_api/filters/parser.py +++ b/src/dso_api/dynamic_api/filters/parser.py @@ -417,6 +417,16 @@ def _translate_raw_value( # noqa: C901 # or ?ligtInPanden=... references their identifier as foreign key. return filter_input.raw_value + if field_schema.is_array_of_objects: + try: + items = field_schema["items"] + parser = SCALAR_PARSERS[items.get("format") or items["type"]] + except KeyError as e: + raise ValidationError( + f"Array of objects field '{filter_part.name}'" + f"should be filtered on with a .subfield" + ) from e + if field_schema.is_array: items = field_schema["items"] parser = SCALAR_PARSERS[items.get("format") or items["type"]] From 7f1800c52fe0cedc85080af4caee734090732a89 Mon Sep 17 00:00:00 2001 From: lotte-amsterdam Date: Thu, 21 May 2026 17:05:04 +0200 Subject: [PATCH 2/2] Added test --- src/dso_api/dynamic_api/filters/parser.py | 2 +- .../test_dynamic_api/views/test_api_filters.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/dso_api/dynamic_api/filters/parser.py b/src/dso_api/dynamic_api/filters/parser.py index 76a2c9599..89d33d929 100644 --- a/src/dso_api/dynamic_api/filters/parser.py +++ b/src/dso_api/dynamic_api/filters/parser.py @@ -423,7 +423,7 @@ def _translate_raw_value( # noqa: C901 parser = SCALAR_PARSERS[items.get("format") or items["type"]] except KeyError as e: raise ValidationError( - f"Array of objects field '{filter_part.name}'" + f"Array of objects field '{filter_part.name}' " f"should be filtered on with a .subfield" ) from e diff --git a/src/tests/test_dynamic_api/views/test_api_filters.py b/src/tests/test_dynamic_api/views/test_api_filters.py index 22e80dc9f..d2b1afb53 100644 --- a/src/tests/test_dynamic_api/views/test_api_filters.py +++ b/src/tests/test_dynamic_api/views/test_api_filters.py @@ -20,6 +20,19 @@ def test_no_such_field(api_client, afval_dataset, filled_router): reason = response.data["invalid-params"][0]["reason"] assert reason == "Field 'nonexistent' does not exist" + @staticmethod + def test_array_of_objects_field(api_client, bag_dataset, filled_router): + """Prove that not filtering on a subfield of an array of objects will crash.""" + response = api_client.get("/v1/bag/verblijfsobjecten/?gebruiksdoel=test") + data = read_response_json(response) + + assert response.status_code == HTTP_400_BAD_REQUEST, data + reason = data["invalid-params"][0]["reason"] + assert ( + reason + == "Array of objects field 'gebruiksdoel' should be filtered on with a .subfield" + ) + @staticmethod @pytest.mark.parametrize( "url",