Fixed #26379 - Documented that first filter() chained to a RelatedManager is sticky.#20085
Conversation
4104dfd to
9519364
Compare
jacobtylerwalls
left a comment
There was a problem hiding this comment.
Great start @annalauraw. I agreed with your hesitance to get too digressive here. Just a few questions.
docs/topics/db/queries.txt
Outdated
| Filters on RelatedManager | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| When calling ``filter()`` on a |
There was a problem hiding this comment.
Curious, does exclude() behave the same? We have one weirdness doc'd here:
django/docs/topics/db/queries.txt
Lines 660 to 664 in a1ce852
There was a problem hiding this comment.
It is probably coherent to talk about exclude() in this context as well. I tried exclude() with our so-far example: https://dryorm.xterm.info/ebqiqyqf. I suppose this behaviour can be called "different from filter()", since e2 is returned despite having taylor as a co-author. i need some time to understand the underlying SQL WHERE clause...
There was a problem hiding this comment.
Ah, okay. I feel like that's the same class of behavior as what I linked to as "one weirdness" above. Simon discusses this in his "What the JOIN?" talk at 39:41, "when negating against a multi-valued relationship..." and calls it a "subquery pushdown".
I don't feel like we have to document the weirdness in detail twice, but I'm open to a sentence that clarifies or maybe links to the other section with details 🤔
There was a problem hiding this comment.
After looking into the exclude() behaviour a bit deeper, I would say that in this case, it behaves similarly to filter(), although implemented differently:
- single exclude(): co-authored entry is not excluded despite matching the exclude criteria
- double exclude(): co-authored entry is excluded as expected
https://dryorm.xterm.info/t6p0rdrc
There was a problem hiding this comment.
I see. Just like the filter() example, the sticky scenario is excluding on something that logically can't exist (a single row referring to both authors). I like how you got this expressed without drowning in details 👍
docs/topics/db/queries.txt
Outdated
| :class:`~django.db.models.fields.related.RelatedManager`, be aware that the | ||
| first method call is "sticky". Consider the following example: |
There was a problem hiding this comment.
There could be an alternative here that leaves the reader in a bit less suspense, not needing to read to the end to finally find out what "sticky" is. Having sat with this, can you think of anything? Maybe:
be aware that the first filter call reuses the blah blah blah—in other words, it's "sticky".
There was a problem hiding this comment.
I will try. I really struggled with a concise explanation and felt the need to move to the example as quickly as possible.
There was a problem hiding this comment.
New version reads well here.
0758729 to
5f9b419
Compare
5f9b419 to
1d446db
Compare
jacobtylerwalls
left a comment
There was a problem hiding this comment.
Thanks for the PR, @annalauraw, this looks great!
docs/topics/db/queries.txt
Outdated
| between one author and one entry - can fulfill the query condition (entries | ||
| that are co-authored by ``anna`` and ``gloria``). You can circumvent this | ||
| behavior by chaining two consecutive ``filter()`` calls, resulting in two | ||
| separate joins and thus a more permissive filter. |
There was a problem hiding this comment.
This reads perfectly, thank you ⭐
docs/topics/db/queries.txt
Outdated
| >>> anna.entry_set.filter().filter(authors__name="Gloria") | ||
| <QuerySet [<Entry: Supporting social movements with drums>]> | ||
|
|
||
| .. note:: |
There was a problem hiding this comment.
We avoid bare notes in favor of an admonition:: my heading so that we can use a heading (I'll add one for you).
docs/topics/db/queries.txt
Outdated
| Filters on RelatedManager | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| When calling ``filter()`` on a |
There was a problem hiding this comment.
I see. Just like the filter() example, the sticky scenario is excluding on something that logically can't exist (a single row referring to both authors). I like how you got this expressed without drowning in details 👍
docs/topics/db/queries.txt
Outdated
| :class:`~django.db.models.fields.related.RelatedManager`, be aware that the | ||
| first method call is "sticky". Consider the following example: |
There was a problem hiding this comment.
New version reads well here.
|
Thank you so much @jacobtylerwalls, that was a great review experience! |
Trac ticket number
ticket-26379
Branch description
Document that first filter() chained to a RelatedManager is sticky. Add heading "Filters on RelatedManager" to docs/topics/db/queries.txt. Document the sticky filter behaviour with a query example based on the models Author and Entry at the top of the docs page.
Checklist
mainbranch.