diff --git a/fastapi_jsonapi/views/view_base.py b/fastapi_jsonapi/views/view_base.py index ddf499da..bbc3c063 100644 --- a/fastapi_jsonapi/views/view_base.py +++ b/fastapi_jsonapi/views/view_base.py @@ -259,7 +259,7 @@ def _prepare_item_data( cls, db_item, resource_type: str, - include_fields: Optional[dict[str, dict[str, Type[TypeSchema]]]] = None, + include_fields: dict[str, dict[str, Type[TypeSchema]]], ) -> dict: attrs_schema = schemas_storage.get_attrs_schema(resource_type, operation_type="get") @@ -387,7 +387,11 @@ def _process_includes( include_key = self._get_include_key(relationship_db_item, info) if not (relationship_item_data := result_included.get(include_key)): - relationship_item_data = self._prepare_item_data(relationship_db_item, info.resource_type) + relationship_item_data = self._prepare_item_data( + relationship_db_item, + info.resource_type, + include_fields=include_fields, + ) result_included[include_key] = relationship_item_data items_data_to_process.append(relationship_item_data) diff --git a/tests/test_api/test_api_sqla_with_includes.py b/tests/test_api/test_api_sqla_with_includes.py index a05fa34c..019ee7d1 100644 --- a/tests/test_api/test_api_sqla_with_includes.py +++ b/tests/test_api/test_api_sqla_with_includes.py @@ -330,6 +330,79 @@ async def test_select_custom_fields_with_includes( ), } + async def test_select_custom_fields_with_includes_other_direction( + self, + app: FastAPI, + async_session: AsyncSession, + client: AsyncClient, + user_1: User, + user_2: User, + ): + url = app.url_path_for("get_post_list") + user_1, user_2 = sorted((user_1, user_2), key=lambda x: x.id) + + user_2_post = await create_post(async_session, user_2) + user_1_post = await create_post(async_session, user_1) + + queried_user_fields = "name" + queried_post_fields = "title" + + params = QueryParams( + [ + ("fields[user]", queried_user_fields), + ("fields[post]", queried_post_fields), + ("include", "user"), + ], + ) + response = await client.get(url, params=f"{params}") + + assert response.status_code == status.HTTP_200_OK, response.text + response_data = response.json() + response_data["data"] = sorted(response_data["data"], key=lambda x: (x["type"], x["id"])) + response_data["included"] = sorted(response_data["included"], key=lambda x: (x["type"], x["id"])) + + assert response_data == { + "data": [ + { + "id": f"{user_2_post.id}", + "type": "post", + "attributes": PostAttributesBaseSchema.model_validate(user_2_post).model_dump( + include=set(queried_post_fields.split(",")), + ), + "relationships": {"user": {"data": {"id": f"{user_2.id}", "type": "user"}}}, + }, + { + "id": f"{user_1_post.id}", + "type": "post", + "attributes": PostAttributesBaseSchema.model_validate(user_1_post).model_dump( + include=set(queried_post_fields.split(",")), + ), + "relationships": {"user": {"data": {"id": f"{user_1.id}", "type": "user"}}}, + }, + ], + "jsonapi": {"version": "1.0"}, + "meta": {"count": 2, "totalPages": 1}, + "included": sorted( + [ + { + "id": f"{user_1.id}", + "type": "user", + "attributes": UserAttributesBaseSchema.model_validate(user_1).model_dump( + include=set(queried_user_fields.split(",")), + ), + }, + { + "id": f"{user_2.id}", + "type": "user", + "attributes": UserAttributesBaseSchema.model_validate(user_2).model_dump( + include=set(queried_user_fields.split(",")), + ), + }, + ], + key=lambda x: (x["type"], x["id"]), + ), + } + async def test_select_custom_fields_for_includes_without_requesting_includes( self, app: FastAPI,