On Mon, Oct 25, 2010 at 6:30 PM, Jumpfroggy <rocketmonk...@gmail.com> wrote:
>
> I have a class like this:
>
> class Node:
>    name = models.CharField()
>    parents = models.ManyToManyField('self', symmetrical=False,
> related_name='child_nodes', null=True, blank=True)
>
> This allows a basic parent(s)/children hierarchy.  A node can have >=
> 0 parents.  A parent can have >= 0 children.
>
> Say I have these nodes:
>
> A - parent node
> B - parent node
> C - child of both A & B
>
> So I can do this:
>
>    Node.objects.filter(name='C')
>    > returns ['C' node].
>
>    Node.objects.filter(name='C', parents__name='A')
>    > returns ['C' node].
>
>    Node.objects.filter(name='C', parents__name='B')
>    > returns ['C' node].
>
>    Node.objects.filter(Q(name='C'), Q(parents__name='A'))
>    > returns ['C' node].
>
>    Node.objects.filter(Q(name='C'), Q(parents__name='B'))
>    > returns ['C' node].
>
>    Node.objects.filter(Q(name='C'), Q(parents__name='A'),
> Q(parents__name='B'))
>    > returns []
>
>    Node.objects.filter(Q(name='C') & Q(parents__name='A') &
> Q(parents__name='B'))
>    > returns []
>
>    Node.objects.filter(Q(parents__name='A'), Q(parents__name='B'))
>    > returns []
>
>
> Why do those last two return an empty set?  I can even do this:
>
>    Node.objects.filter(Q(name='C'),
> Q(parents__name='A')).filter(Q(parents__name='B'))
>    > returns ['C' node].
>
> That works.  But filtering on two parents (AND, not OR... I want the
> child nodes of both parents) returns the empty set.  It doesn't make
> sense to me why using two separate filters would work, but combining
> them into one statement gives different results.
>
> Anyone have an idea about this?  Is this a bug in the django query
> system, or am I looking at this wrong?  Thanks.
>

You're looking at it wrong. When you put multiple filter specs into
one filter call for a m2m join, what you are actually doing is adding
extra conditions to the m2m join.

So this one:

Node.objects.filter(Q(parents__name='A'), Q(parents__name='B'))

This is looking for a single node who has a single parent whose name
is both 'A' and 'B' - unlikely!

And this one:

Node.objects.filter(Q(parents__name='A')).filter(Q(parents__name='B'))

This is looking for a node which has a parent with name A, and a
parent with name B.

This is all clearly documented, see here:

http://docs.djangoproject.com/en/1.2/topics/db/queries/#spanning-multi-valued-relationships

Cheers

Tom

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to