Opened 11 years ago

Closed 11 years ago

Last modified 7 years ago

#8046 closed (fixed)

filter() on a related multi-valued manager joins to too many tables.

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


Because related managers are treated as filter() calls internally, filtering on a related attribute is the same as chained filter() calls, which leads to unintuitive behaviour on many-to-many relations and reverse ForeignKey relations.

Change History (6)

comment:1 Changed 11 years ago by Malcolm Tredinnick

Triage Stage: UnreviewedAccepted

comment:2 Changed 11 years ago by Malcolm Tredinnick

This isn't the bug I thought it was (at least, I can't repeat the original situation where I though I saw something going wrong). There's still a problem, as indicated in this thread, there's still some likely incorrect behaviour with ManyToManyField(through=...).

Any subsequent filters are being treated as extra filters and joining separately to the intermediate table. The caller has no way to say it's the same filter (equivalent to filter(thingA, thingB)) (which is why this is a bug). We should, by default, be treating the first filter as a continuation of the related object filtering and if somebody ahs a case where they don't want that, an intermediate call to all() will force them apart. The "natural" behaviour will almost always be correct here, though.

I'll still fix it -- it's not too hard to do, from what I can see -- but I just spent two hours trying to work out the original case (and failing) and cursing myself for not including more info in the bug report. So I'm now fixing that with what I understand the problem to be now.

comment:3 Changed 11 years ago by Joshua Uziel

And to summarize that post of mine: "There should be a clean way to query a M2M relationship and filter based on the intermediate table." Right now, the ManyToManyField(through=...) feature doesn't appear to work that way, and I'll argue that it's confusing and incorrect... and I'm glad you (seem to) agree with me, Malcolm.

By all means, let me know if there's anything you'd like me to help with or test.

comment:5 Changed 11 years ago by Malcolm Tredinnick

Resolution: fixed
Status: newclosed

(In [8472]) Fixed #8046 -- The first filter() call on a related manager for many-to-many
fields no longer creates duplicate copies of the join table(s). Basically, this
means filters on the join table (for ManyToManyField(through=...)) and complex
filters in the normal (non-through) case don't produce incorrect or duplicate

comment:6 Changed 7 years ago by Jacob

milestone: 1.0

Milestone 1.0 deleted

Note: See TracTickets for help on using tickets.
Back to Top