From b5d437bc2741929a9ab4b8b736cea78337fe34a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tao=20Bojl=C3=A9n?= <66130243+taobojlen@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:53:45 +0000 Subject: [PATCH] fix: use correct field name in forward many-to-many fields --- src/zeal/patch.py | 5 ++++- tests/test_nplusones.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/zeal/patch.py b/src/zeal/patch.py index 58995bb..7a7657d 100644 --- a/src/zeal/patch.py +++ b/src/zeal/patch.py @@ -229,7 +229,10 @@ def parser(context: QuerysetContext) -> QuerySource: manager = context["args"][0] model = manager.instance.__class__ related_model = manager.target_field.related_model - field_name = manager.prefetch_cache_name if rel.related_name else None + is_reverse = context["manager_call_args"]["reverse"] + field_name = ( + rel.related_name if is_reverse else manager.prefetch_cache_name + ) model, field_name = parse_related_parts( model, field_name, related_model diff --git a/tests/test_nplusones.py b/tests/test_nplusones.py index a1b8377..76e4f6e 100644 --- a/tests/test_nplusones.py +++ b/tests/test_nplusones.py @@ -365,6 +365,20 @@ def test_no_false_positive_when_loading_single_object_reverse_many_to_many(): assert len(ctx.captured_queries) == 2 +def test_detects_nplusone_in_forward_many_to_many_with_no_related_name(): + [user_1, user_2] = UserFactory.create_batch(2) + user_1.blocked.add(user_2) + user_2.blocked.add(user_1) + with pytest.raises( + NPlusOneError, match=re.escape("N+1 detected on social.User.blocked") + ): + for user in User.objects.all(): + _ = list(user.blocked.all()) + + for user in User.objects.prefetch_related("blocked").all(): + _ = list(user.blocked.all()) + + def test_detects_nplusone_in_reverse_many_to_many_with_no_related_name(): [user_1, user_2] = UserFactory.create_batch(2) user_1.blocked.add(user_2)