In the case where you want to select a primary object that has related
objects of one type, but none of another, you could use a Q like this:
`q = Q(Q(relatedobject__someparam=True),
~Q(relatedobject__someparam=False))`
`results = PrimaryObject.objects.filter(q)`
Using this Q in a filter in 1.6.7 would give you all primary objects that
have relatedobjects with someparam=True and omit any primary objects that
also had a relatedobject with someparam=False. In 1.7 these objects are
returned despite the ~Q(relatedobject__someparam=False).
This gist provides a sample to illustrate the problem:
https://gist.github.com/scottsexton/375f7869839a98593695
--
Ticket URL: <https://code.djangoproject.com/ticket/23589>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
Old description:
> The behavior of Q objects has changed in an undocumented and breaking way
> for m2m relationships in Django 1.7 from the behavior in 1.6.7, returning
> different query results depending on the Django version.
>
> In the case where you want to select a primary object that has related
> objects of one type, but none of another, you could use a Q like this:
> `q = Q(Q(relatedobject__someparam=True),
> ~Q(relatedobject__someparam=False))`
> `results = PrimaryObject.objects.filter(q)`
>
> Using this Q in a filter in 1.6.7 would give you all primary objects that
> have relatedobjects with someparam=True and omit any primary objects that
> also had a relatedobject with someparam=False. In 1.7 these objects are
> returned despite the ~Q(relatedobject__someparam=False).
>
> This gist provides a sample to illustrate the problem:
> https://gist.github.com/scottsexton/375f7869839a98593695
New description:
The behavior of Q objects has changed in an undocumented and breaking way
for m2m relationships in Django 1.7 from the behavior in 1.6.7, returning
different query results depending on the Django version.
In the case where you want to select a primary object that has related
objects of one type, but none of another, you could use a Q like this:
`q = Q(Q(relatedobject__someparam=True),
~Q(relatedobject__someparam=False))`
`results = PrimaryObject.objects.filter(q)`
Using this Q in a filter in 1.6.7 would give you all primary objects that
have relatedobjects with someparam=True and omit any primary objects that
also had a relatedobject with someparam=False. In 1.7 these objects are
returned despite the `~Q(relatedobject__someparam=False)`.
This gist provides a sample to illustrate the problem:
https://gist.github.com/scottsexton/375f7869839a98593695
--
Comment:
It would be helpful if you could create a test for Django's test suite
that demonstrates the issue (ideally reusing existing models if you can
find appropriate ones) and bisect to the commit that introduced the
regression.
--
Ticket URL: <https://code.djangoproject.com/ticket/23589#comment:1>
* status: new => closed
* resolution: => invalid
Comment:
The interpretation of the query is that PrimaryObject must have a *single*
relatedobject row for which (someparam=True AND NOT someparam=False).
Obviously if someparam=True, then someparam is also not False for that
row. The 1.7 results seem correct to me. (See
https://docs.djangoproject.com/en/1.7/topics/db/queries/#spanning-multi-
valued-relationships for how Django handles filters to multivalued
relationships).
I believe you will get correct results by using
`.filter(Q(relatedobject__someparam=True)).filter(~Q(relatedobject__someparam=False))`.
--
Ticket URL: <https://code.djangoproject.com/ticket/23589#comment:2>
Comment (by Grafumbly):
The documentation hasn't changed but the behavior has. If this is working
as intended in 1.7, is it a bug in 1.6 or does the documentation just need
to be updated?
--
Ticket URL: <https://code.djangoproject.com/ticket/23589#comment:3>
Comment (by akaariai):
Yes, this was a bug in 1.6. This is an unfortunate bug, as you might have
gotten correct results. That is, the query worked, but didn't match the
documentation. The query produced results for
`.filter(Q(relatedobject__someparam=True)).filter(~Q(relatedobject__someparam=False))`.
--
Ticket URL: <https://code.djangoproject.com/ticket/23589#comment:4>