Code

Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#15161 closed (fixed)

ManyToManyField with a through model with to_field set returns no results

Reported by: adehnert Owned by: carljm
Component: Database layer (models, ORM) Version: 1.2
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

If you create a model that has a ManyToManyField with through=IntermediateModel, and you set to_field on one of the ForeignKeys in the IntermediateModel, the ManyToManyField won't properly produce the right set of results.

For example, using the attached set of models, I get:

>>> import manytomany.models
>>> foobar = manytomany.models.FooBar.objects.all()[0]
>>> foobar
<FooBar: pk=1 foo=1 bar=1: bar>
>>> manytomany.models.FooBar.objects.filter(foo=foobar.foo)
[<FooBar: pk=1 foo=1 bar=1: bar>]
>>> foobar.foo.bars.all()
[]
>>> foobar2 = manytomany.models.FooBar2.objects.all()[0]
>>> foobar2
<FooBar2: pk=1 foo=1 bar=1: bar2>
>>> manytomany.models.FooBar2.objects.filter(foo=foobar2.foo)
[<FooBar2: pk=1 foo=1 bar=1: bar2>]
>>> foobar2.foo.bars.all()
[<Bar2: 1: bar2>]

I would expect filter(foo=foo) to produce basically the same set of results as foo.bars (except with the FooBar objects instead of the Bar objects). However, while the former produces results, the latter does not.

I suspect this is related to the behavior experienced in http://www.mail-archive.com/django-users@googlegroups.com/msg105967.html. However, while that seems like arguably not a bug, this behavior does seem to clearly qualify (or, at least, should be better-documented than I was finding it to be).

Attachments (1)

models.py (1.1 KB) - added by adehnert 3 years ago.
Example models.py to reproduce

Download all attachments as: .zip

Change History (5)

Changed 3 years ago by adehnert

Example models.py to reproduce

comment:1 Changed 3 years ago by carljm

  • Needs documentation unset
  • Needs tests unset
  • Owner changed from nobody to carljm
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

comment:2 Changed 3 years ago by carljm

Fix here: https://github.com/carljm/django/compare/master...t15161

Pretty sure this could be RFC (all tests pass), but it's late, so I'll sleep on it. I'm a little unhappy with the lambda contortions needed to go two attribute layers deep with the curried _get_m2m_attr business. I'd like to at least consider avoiding the lambda dance with a larger refactor of that attribute-fetching mechanism. Downside is that said refactor is sure to break some third-party code (django-taggit, for example), despite those m2m APIs not being documented.

comment:3 Changed 3 years ago by carljm

  • Resolution set to fixed
  • Status changed from new to closed

(In [15330]) Fixed #15161 - Corrected handling of ManyToManyField with through table using to_field on its ForeignKeys. Thanks to adehnert for the report.

comment:4 Changed 3 years ago by carljm

(In [15331]) [1.2.X] Fixed #15161 - Corrected handling of ManyToManyField with through table using to_field on its ForeignKeys. Thanks to adehnert for the report.

Backport of r15330 from trunk.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.