Merged the queryset-refactor branch into trunk.
[fdr-django.git] / tests / modeltests / or_lookups / models.py
blobc779e19e37e04989e78bb9348cae28b0daf089b5
1 """
2 19. OR lookups
4 To perform an OR lookup, or a lookup that combines ANDs and ORs,
5 combine QuerySet objects using & and | operators.
7 Alternatively, use positional arguments, and pass one or more expressions of
8 clauses using the variable ``django.db.models.Q`` (or any object with an
9 add_to_query method).
10 """
12 from django.db import models
14 class Article(models.Model):
15 headline = models.CharField(max_length=50)
16 pub_date = models.DateTimeField()
18 class Meta:
19 ordering = ('pub_date',)
21 def __unicode__(self):
22 return self.headline
24 __test__ = {'API_TESTS':"""
25 >>> from datetime import datetime
26 >>> from django.db.models import Q
28 >>> a1 = Article(headline='Hello', pub_date=datetime(2005, 11, 27))
29 >>> a1.save()
31 >>> a2 = Article(headline='Goodbye', pub_date=datetime(2005, 11, 28))
32 >>> a2.save()
34 >>> a3 = Article(headline='Hello and goodbye', pub_date=datetime(2005, 11, 29))
35 >>> a3.save()
37 >>> Article.objects.filter(headline__startswith='Hello') | Article.objects.filter(headline__startswith='Goodbye')
38 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
40 >>> Article.objects.filter(Q(headline__startswith='Hello') | Q(headline__startswith='Goodbye'))
41 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
43 >>> Article.objects.filter(Q(headline__startswith='Hello') & Q(headline__startswith='Goodbye'))
46 # You can shorten this syntax with code like the following,
47 # which is especially useful if building the query in stages:
48 >>> articles = Article.objects.all()
49 >>> articles.filter(headline__startswith='Hello') & articles.filter(headline__startswith='Goodbye')
52 >>> articles.filter(headline__startswith='Hello') & articles.filter(headline__contains='bye')
53 [<Article: Hello and goodbye>]
55 >>> Article.objects.filter(Q(headline__contains='bye'), headline__startswith='Hello')
56 [<Article: Hello and goodbye>]
58 >>> Article.objects.filter(headline__contains='Hello') | Article.objects.filter(headline__contains='bye')
59 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
61 >>> Article.objects.filter(headline__iexact='Hello') | Article.objects.filter(headline__contains='ood')
62 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
64 >>> Article.objects.filter(Q(pk=1) | Q(pk=2))
65 [<Article: Hello>, <Article: Goodbye>]
67 >>> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
68 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
70 # You could also use "in" to accomplish the same as above.
71 >>> Article.objects.filter(pk__in=[1,2,3])
72 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
73 >>> Article.objects.filter(pk__in=(1,2,3))
74 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
76 >>> Article.objects.filter(pk__in=[1,2,3,4])
77 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
79 # Passing "in" an empty list returns no results ...
80 >>> Article.objects.filter(pk__in=[])
83 # ... but can return results if we OR it with another query.
84 >>> Article.objects.filter(Q(pk__in=[]) | Q(headline__icontains='goodbye'))
85 [<Article: Goodbye>, <Article: Hello and goodbye>]
87 # Q arg objects are ANDed
88 >>> Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye'))
89 [<Article: Hello and goodbye>]
91 # Q arg AND order is irrelevant
92 >>> Article.objects.filter(Q(headline__contains='bye'), headline__startswith='Hello')
93 [<Article: Hello and goodbye>]
95 # Q objects can be negated
96 >>> Article.objects.filter(Q(pk=1) | ~Q(pk=2))
97 [<Article: Hello>, <Article: Hello and goodbye>]
98 >>> Article.objects.filter(~Q(pk=1) & ~Q(pk=2))
99 [<Article: Hello and goodbye>]
101 # This allows for more complex queries than filter() and exclude() alone would
102 # allow
103 >>> Article.objects.filter(Q(pk=1) & (~Q(pk=2) | Q(pk=3)))
104 [<Article: Hello>]
106 # Try some arg queries with operations other than filter.
107 >>> Article.objects.get(Q(headline__startswith='Hello'), Q(headline__contains='bye'))
108 <Article: Hello and goodbye>
110 >>> Article.objects.filter(Q(headline__startswith='Hello') | Q(headline__contains='bye')).count()
113 >>> list(Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye')).values())
114 [{'headline': u'Hello and goodbye', 'pub_date': datetime.datetime(2005, 11, 29, 0, 0), 'id': 3}]
116 >>> Article.objects.filter(Q(headline__startswith='Hello')).in_bulk([1,2])
117 {1: <Article: Hello>}
119 # Demonstrating exclude with a Q object
120 >>> Article.objects.exclude(Q(headline__startswith='Hello'))
121 [<Article: Goodbye>]
123 # The 'complex_filter' method supports framework features such as
124 # 'limit_choices_to' which normally take a single dictionary of lookup arguments
125 # but need to support arbitrary queries via Q objects too.
126 >>> Article.objects.complex_filter({'pk': 1})
127 [<Article: Hello>]
128 >>> Article.objects.complex_filter(Q(pk=1) | Q(pk=2))
129 [<Article: Hello>, <Article: Goodbye>]
130 """}