Ticket #11914: m2

File m2, 2.2 KB (added by jafo3, 15 years ago)

My proposed documentation change.

Line 
1<h2 id="model-multiple-membership">Membership in Multiple Objects</h2>
2
3<p>Things can get a little tricky when you want to check for membership
4of one object in several objects in the other side of a
5<tt class="docutils literal"><span class="pre">ManyToManyField()</span></tt>
6relationship. For example, if you want to only show articles that are
7<b>only</b> published in The Python Journal and Science Weekly, but not
8Highlights for Children.</p>
9
10<p>The problem here is that the simple, obvious syntax results in
11checking if an article was in a <b>single</b> Publication that was
12titled "The Python Journal" <b>and</b> "Science Weekly", but not
13"Highlights for Children". Remember, the simple, obvious, syntax
14looks for a <b>single</b> publication which matches all three of these
15criteria.</p>
16
17<p>Here are some examples of how not to do it, followed by ways to
18accomplish it:</p>
19
20
21<pre class="literal-block">
22# WARNING: This syntax DOES NOT WORK:
23>>> Article.objects.filter(
24... ( Q(publications__title = 'The Python Journal')
25... | Q(publications__title = 'Science Weekly'))
26... & ~Q(publications__title = 'Highlights for Children'))
27[]
28
29# What we have to do is use the ".extra()" method to add some addition
30# WHERE clauses to do what we need:
31>>> Article.objects.extra(where = [ '''
32... (SELECT COUNT(*) FROM publication, articlepublications
33... WHERE article.id = articlepublications.article_id
34... AND articlepublications.publication_id = publication.id
35... AND publication.title = 'The Python Journal') > 0 ''']
36... ).extra(where = [ '''
37... (SELECT COUNT(*) FROM publication, articlepublications
38... WHERE article.id = articlepublications.article_id
39... AND articlepublications.publication_id = publication.id
40... AND publication.title = 'Science Weekly') > 0 ''']
41... ).extra(where = [ '''
42... (SELECT COUNT(*) FROM publication, articlepublications
43... WHERE article.id = articlepublications.article_id
44... AND articlepublications.publication_id = publication.id
45... AND publication.title = 'Highlights for Children') = 0 '''])
46[<Article: NASA uses Python>]
47</pre>
Back to Top