<h2 id="model-multiple-membership">Membership in Multiple Objects</h2>

<p>Things can get a little tricky when you want to check for membership
of one object in several objects in the other side of a 
<tt class="docutils literal"><span class="pre">ManyToManyField()</span></tt>
relationship.  For example, if you want to only show articles that are
<b>only</b> published in The Python Journal and Science Weekly, but not
Highlights for Children.</p>

<p>The problem here is that the simple, obvious syntax results in
checking if an article was in a <b>single</b> Publication that was
titled "The Python Journal" <b>and</b> "Science Weekly", but not
"Highlights for Children".  Remember, the simple, obvious, syntax
looks for a <b>single</b> publication which matches all three of these
criteria.</p>

<p>Here are some examples of how not to do it, followed by ways to
accomplish it:</p>


<pre class="literal-block">
#  WARNING: This syntax DOES NOT WORK:
>>> Article.objects.filter(
...    ( Q(publications__title = 'The Python Journal')
...       | Q(publications__title = 'Science Weekly'))
...    & ~Q(publications__title = 'Highlights for Children'))
[]

#  What we have to do is use the ".extra()" method to add some addition
#  WHERE clauses to do what we need:
>>> Article.objects.extra(where = [ '''
...          (SELECT COUNT(*) FROM publication, articlepublications
...             WHERE article.id = articlepublications.article_id
...             AND articlepublications.publication_id = publication.id
...             AND publication.title = 'The Python Journal') > 0 ''']
...    ).extra(where = [ '''
...          (SELECT COUNT(*) FROM publication, articlepublications
...             WHERE article.id = articlepublications.article_id
...             AND articlepublications.publication_id = publication.id
...             AND publication.title = 'Science Weekly') > 0 ''']
...    ).extra(where = [ '''
...          (SELECT COUNT(*) FROM publication, articlepublications
...             WHERE article.id = articlepublications.article_id
...             AND articlepublications.publication_id = publication.id
...             AND publication.title = 'Highlights for Children') = 0 '''])
[<Article: NASA uses Python>]
</pre>
