[Django] #36291: ManyToManyField empty when setting related_name and related_query_name to "+"

3 views
Skip to first unread message

Django

unread,
Apr 2, 2025, 9:57:10 PM4/2/25
to django-...@googlegroups.com
#36291: ManyToManyField empty when setting related_name and related_query_name to
"+"
-------------------------------------+-------------------------------------
Reporter: iamhayder | Type: Bug
Status: new | Component: Database
| layer (models, ORM)
Version: 5.2 | Severity: Normal
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
I’ve encountered an issue in my Django project where using the following
configuration in a ManyToManyField causes the field to return an empty
queryset—even though the underlying join table contains records. Notably,
this bug appears to be intermittent; sometimes the field behaves as
expected, while other times it consistently returns an empty queryset.


{{{
move_lines = models.ManyToManyField(
"accounting.AccountMoveLine",
verbose_name="Move Lines",
related_name="+",
related_query_name="+",
blank=True,
)
}}}


Steps to Reproduce:

Define a model with a ManyToManyField that includes related_name="+" and
related_query_name="+" (to disable reverse relations).

Create and save related records so that there are entries in the join
table.

Query the field using instance.move_lines.all().

Observe that the queryset is empty despite the related records existing.
Note that the bug does not occur consistently—there are occasions where
the field returns the expected records.

Expected Behavior:
The field should return all associated records when queried, regardless of
the reverse relation being disabled.

Actual Behavior:
When related_name and related_query_name are set to "+",
instance.move_lines.all() sometimes returns an empty queryset even though
related records exist. Removing these attributes (thus allowing Django to
generate default reverse names) consistently resolves the issue.

Additional Context:
This appears to be an issue where disabling the reverse relationship by
setting the related names to "+" intermittently interferes with the ORM’s
ability to construct the proper join, resulting in an empty result set on
the forward lookup. Has anyone else experienced this behavior, or is there
a known workaround or fix for this issue?

Thanks in advance for any help or insights!
--
Ticket URL: <https://code.djangoproject.com/ticket/36291>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Apr 3, 2025, 3:24:07 AM4/3/25
to django-...@googlegroups.com
#36291: ManyToManyField empty when setting related_name and related_query_name to
"+"
-------------------------------------+-------------------------------------
Reporter: Hayder Mustafa | Owner: (none)
Type: Bug | Status: closed
Component: Database layer | Version: 5.2
(models, ORM) | Resolution:
Severity: Normal | worksforme
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* resolution: => worksforme
* status: new => closed

Comment:

I cannot replicate, can you try to write a regression test?

This was what I have tested:

{{{#!diff
--- a/tests/m2m_regress/tests.py
+++ b/tests/m2m_regress/tests.py
@@ -11,6 +11,7 @@ from .models import (
SelfReferChildSibling,
Tag,
TagCollection,
+ Test,
Worksheet,
)

@@ -141,3 +142,13 @@ class M2MRegressionTests(TestCase):
post.secondary_lines.add(bar)
self.assertSequenceEqual(post.primary_lines.all(), [foo])
self.assertSequenceEqual(post.secondary_lines.all(), [bar])
+
+ def test_related_name_and_related_query_name_plus(self):
+ instance = Test.objects.create()
+ foo = Line.objects.create(name="foo")
+ bar = Line.objects.create(name="bar")
+ instance.lines.add(foo)
+ instance.lines.add(bar)
+ self.assertSequenceEqual(instance.lines.all(), [foo, bar])
+ instance.refresh_from_db()
+ self.assertSequenceEqual(instance.lines.all(), [foo, bar])
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36291#comment:1>
Reply all
Reply to author
Forward
0 new messages