From 13a8655126138d282261fbebc2e1dc62348f04a5 Mon Sep 17 00:00:00 2001 From: collerek Date: Sun, 6 Jun 2021 15:58:38 +0200 Subject: [PATCH] exclude through models --- docs/relations/many-to-many.md | 2 +- ormar/models/model_row.py | 6 +- .../test_selecting_subset_of_columns.py | 55 +++++++++++++++++++ .../test_values_and_values_list.py | 3 +- 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/docs/relations/many-to-many.md b/docs/relations/many-to-many.md index be48cdb..a6fc229 100644 --- a/docs/relations/many-to-many.md +++ b/docs/relations/many-to-many.md @@ -168,7 +168,7 @@ By default `Through` model relation names default to related model name in lower So in example like this: ```python -... # course declaration ommited +... # course declaration omitted class Student(ormar.Model): class Meta: database = database diff --git a/ormar/models/model_row.py b/ormar/models/model_row.py index 461cf9b..3c2dd1c 100644 --- a/ormar/models/model_row.py +++ b/ormar/models/model_row.py @@ -217,7 +217,11 @@ class ModelRow(NewBaseModel): used_prefixes=used_prefixes, ) item[model_cls.get_column_name_from_alias(related)] = child - if field.is_multi and child: + if ( + field.is_multi + and child + and not model_excludable.is_excluded(field.through.get_name()) + ): cls._populate_through_instance( row=row, item=item, diff --git a/tests/test_queries/test_selecting_subset_of_columns.py b/tests/test_queries/test_selecting_subset_of_columns.py index 78168db..1c68a6a 100644 --- a/tests/test_queries/test_selecting_subset_of_columns.py +++ b/tests/test_queries/test_selecting_subset_of_columns.py @@ -230,3 +230,58 @@ async def test_selecting_subset(): await Car.objects.select_related("manufacturer").fields( ["id", "name", "manufacturer__founded"] ).all() + + +@pytest.mark.asyncio +async def test_selecting_subset_of_through_model(): + async with database: + car = ( + await Car.objects.select_related(["manufacturer__hq__nicks"]) + .fields( + { + "id": ..., + "name": ..., + "manufacturer": { + "name": ..., + "hq": {"name": ..., "nicks": {"name": ...}}, + }, + } + ) + .exclude_fields("manufacturer__hq__nickshq") + .get() + ) + assert car.manufacturer.hq.nicks[0].nickshq is None + + car = ( + await Car.objects.select_related(["manufacturer__hq__nicks"]) + .fields( + { + "id": ..., + "name": ..., + "manufacturer": { + "name": ..., + "hq": {"name": ..., "nicks": {"name": ...}}, + }, + } + ) + .exclude_fields({"manufacturer": {"hq": {"nickshq": ...}}}) + .get() + ) + assert car.manufacturer.hq.nicks[0].nickshq is None + + car = ( + await Car.objects.select_related(["manufacturer__hq__nicks"]) + .fields( + { + "id": ..., + "name": ..., + "manufacturer": { + "name": ..., + "hq": {"name": ..., "nicks": {"name": ...}}, + }, + } + ) + .exclude_fields("manufacturer__hq__nickshq__nick") + .get() + ) + assert car.manufacturer.hq.nicks[0].nickshq is not None diff --git a/tests/test_queries/test_values_and_values_list.py b/tests/test_queries/test_values_and_values_list.py index 178ade1..fa4be2b 100644 --- a/tests/test_queries/test_values_and_values_list.py +++ b/tests/test_queries/test_values_and_values_list.py @@ -261,7 +261,8 @@ async def test_nested_m2m_values_subset_of_fields(): user = ( await Role.objects.select_related("users__categories") .filter(name="admin") - .fields({"name": ..., "users": {"name": ...}}) + .fields({"name": ..., "users": {"name": ..., "categories": {"name"}}}) + .exclude_fields("users__roleuser") .values() ) assert user == [