Skip to content

Commit 837d582

Browse files
author
Mark Dufour
committed
fix for custom fields for includes (many-to-one direction)
by passing missing include_fields parameter.
1 parent a1a4fc5 commit 837d582

File tree

2 files changed

+93
-2
lines changed

2 files changed

+93
-2
lines changed

fastapi_jsonapi/views/view_base.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def _prepare_item_data(
259259
cls,
260260
db_item,
261261
resource_type: str,
262-
include_fields: Optional[dict[str, dict[str, Type[TypeSchema]]]] = None,
262+
include_fields: dict[str, dict[str, Type[TypeSchema]]],
263263
) -> dict:
264264
attrs_schema = schemas_storage.get_attrs_schema(resource_type, operation_type="get")
265265

@@ -387,7 +387,11 @@ def _process_includes(
387387
include_key = self._get_include_key(relationship_db_item, info)
388388

389389
if not (relationship_item_data := result_included.get(include_key)):
390-
relationship_item_data = self._prepare_item_data(relationship_db_item, info.resource_type)
390+
relationship_item_data = self._prepare_item_data(
391+
relationship_db_item,
392+
info.resource_type,
393+
include_fields=include_fields,
394+
)
391395
result_included[include_key] = relationship_item_data
392396

393397
items_data_to_process.append(relationship_item_data)

tests/test_api/test_api_sqla_with_includes.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,93 @@ async def test_select_custom_fields_with_includes(
330330
),
331331
}
332332

333+
async def test_select_custom_fields_with_includes_other_direction(
334+
self,
335+
app: FastAPI,
336+
async_session: AsyncSession,
337+
client: AsyncClient,
338+
user_1: User,
339+
user_2: User,
340+
):
341+
url = app.url_path_for("get_post_list")
342+
user_1, user_2 = sorted((user_1, user_2), key=lambda x: x.id)
343+
344+
user_2_post = await create_post(async_session, user_2)
345+
user_1_post = await create_post(async_session, user_1)
346+
347+
queried_user_fields = "name"
348+
queried_post_fields = "title"
349+
350+
params = QueryParams(
351+
[
352+
("fields[user]", queried_user_fields),
353+
("fields[post]", queried_post_fields),
354+
("include", "user"),
355+
],
356+
)
357+
response = await client.get(url, params=f"{params}")
358+
359+
assert response.status_code == status.HTTP_200_OK, response.text
360+
response_data = response.json()
361+
response_data["data"] = sorted(response_data["data"], key=lambda x: (x["type"], x["id"]))
362+
response_data["included"] = sorted(response_data["included"], key=lambda x: (x["type"], x["id"]))
363+
364+
assert response_data == {
365+
"data": [
366+
{
367+
"id": f"{user_2_post.id}",
368+
"type": "post",
369+
"attributes": PostAttributesBaseSchema.model_validate(user_2_post).model_dump(
370+
include=set(queried_post_fields.split(","))
371+
),
372+
"relationships": {
373+
"user": {
374+
"data": {
375+
"id": f"{user_2.id}",
376+
"type": "user"
377+
}
378+
}
379+
}
380+
},
381+
{
382+
"id": f"{user_1_post.id}",
383+
"type": "post",
384+
"attributes": PostAttributesBaseSchema.model_validate(user_1_post).model_dump(
385+
include=set(queried_post_fields.split(","))
386+
),
387+
"relationships": {
388+
"user": {
389+
"data": {
390+
"id": f"{user_1.id}",
391+
"type": "user"
392+
}
393+
}
394+
}
395+
},
396+
],
397+
"jsonapi": {"version": "1.0"},
398+
"meta": { "count": 2, "totalPages": 1 },
399+
"included": sorted(
400+
[
401+
{
402+
"id": f"{user_1.id}",
403+
"type": "user",
404+
"attributes": UserAttributesBaseSchema.model_validate(user_1).model_dump(
405+
include=set(queried_user_fields.split(",")),
406+
),
407+
},
408+
{
409+
"id": f"{user_2.id}",
410+
"type": "user",
411+
"attributes": UserAttributesBaseSchema.model_validate(user_2).model_dump(
412+
include=set(queried_user_fields.split(",")),
413+
),
414+
},
415+
],
416+
key=lambda x: (x["type"], x["id"]),
417+
),
418+
}
419+
333420
async def test_select_custom_fields_for_includes_without_requesting_includes(
334421
self,
335422
app: FastAPI,

0 commit comments

Comments
 (0)