1 """ |
|
2 19. OR lookups |
|
3 |
|
4 To perform an OR lookup, or a lookup that combines ANDs and ORs, |
|
5 combine QuerySet objects using & and | operators. |
|
6 |
|
7 Alternatively, use positional arguments, and pass one or more expressions |
|
8 of clauses using the variable ``django.db.models.Q`` (or any object with |
|
9 a get_sql method). |
|
10 |
|
11 |
|
12 """ |
|
13 |
|
14 from django.db import models |
|
15 |
|
16 class Article(models.Model): |
|
17 headline = models.CharField(maxlength=50) |
|
18 pub_date = models.DateTimeField() |
|
19 |
|
20 class Meta: |
|
21 ordering = ('pub_date',) |
|
22 |
|
23 def __str__(self): |
|
24 return self.headline |
|
25 |
|
26 __test__ = {'API_TESTS':""" |
|
27 >>> from datetime import datetime |
|
28 >>> from django.db.models import Q |
|
29 |
|
30 >>> a1 = Article(headline='Hello', pub_date=datetime(2005, 11, 27)) |
|
31 >>> a1.save() |
|
32 |
|
33 >>> a2 = Article(headline='Goodbye', pub_date=datetime(2005, 11, 28)) |
|
34 >>> a2.save() |
|
35 |
|
36 >>> a3 = Article(headline='Hello and goodbye', pub_date=datetime(2005, 11, 29)) |
|
37 >>> a3.save() |
|
38 |
|
39 >>> Article.objects.filter(headline__startswith='Hello') | Article.objects.filter(headline__startswith='Goodbye') |
|
40 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>] |
|
41 |
|
42 >>> Article.objects.filter(Q(headline__startswith='Hello') | Q(headline__startswith='Goodbye')) |
|
43 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>] |
|
44 |
|
45 >>> Article.objects.filter(Q(headline__startswith='Hello') & Q(headline__startswith='Goodbye')) |
|
46 [] |
|
47 |
|
48 # You can shorten this syntax with code like the following, |
|
49 # which is especially useful if building the query in stages: |
|
50 >>> articles = Article.objects.all() |
|
51 >>> articles.filter(headline__startswith='Hello') & articles.filter(headline__startswith='Goodbye') |
|
52 [] |
|
53 |
|
54 >>> articles.filter(headline__startswith='Hello') & articles.filter(headline__contains='bye') |
|
55 [<Article: Hello and goodbye>] |
|
56 |
|
57 >>> Article.objects.filter(Q(headline__contains='bye'), headline__startswith='Hello') |
|
58 [<Article: Hello and goodbye>] |
|
59 |
|
60 >>> Article.objects.filter(headline__contains='Hello') | Article.objects.filter(headline__contains='bye') |
|
61 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>] |
|
62 |
|
63 >>> Article.objects.filter(headline__iexact='Hello') | Article.objects.filter(headline__contains='ood') |
|
64 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>] |
|
65 |
|
66 >>> Article.objects.filter(Q(pk=1) | Q(pk=2)) |
|
67 [<Article: Hello>, <Article: Goodbye>] |
|
68 |
|
69 >>> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3)) |
|
70 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>] |
|
71 |
|
72 # You could also use "in" to accomplish the same as above. |
|
73 >>> Article.objects.filter(pk__in=[1,2,3]) |
|
74 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>] |
|
75 |
|
76 >>> Article.objects.filter(pk__in=[1,2,3,4]) |
|
77 [<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>] |
|
78 |
|
79 # Passing "in" an empty list returns no results ... |
|
80 >>> Article.objects.filter(pk__in=[]) |
|
81 [] |
|
82 |
|
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>] |
|
86 |
|
87 # Q arg objects are ANDed |
|
88 >>> Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye')) |
|
89 [<Article: Hello and goodbye>] |
|
90 |
|
91 # Q arg AND order is irrelevant |
|
92 >>> Article.objects.filter(Q(headline__contains='bye'), headline__startswith='Hello') |
|
93 [<Article: Hello and goodbye>] |
|
94 |
|
95 # Try some arg queries with operations other than get_list |
|
96 >>> Article.objects.get(Q(headline__startswith='Hello'), Q(headline__contains='bye')) |
|
97 <Article: Hello and goodbye> |
|
98 |
|
99 >>> Article.objects.filter(Q(headline__startswith='Hello') | Q(headline__contains='bye')).count() |
|
100 3 |
|
101 |
|
102 >>> list(Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye')).values()) |
|
103 [{'headline': 'Hello and goodbye', 'pub_date': datetime.datetime(2005, 11, 29, 0, 0), 'id': 3}] |
|
104 |
|
105 >>> Article.objects.filter(Q(headline__startswith='Hello')).in_bulk([1,2]) |
|
106 {1: <Article: Hello>} |
|
107 |
|
108 # Demonstrating exclude with a Q object |
|
109 >>> Article.objects.exclude(Q(headline__startswith='Hello')) |
|
110 [<Article: Goodbye>] |
|
111 |
|
112 # The 'complex_filter' method supports framework features such as |
|
113 # 'limit_choices_to' which normally take a single dictionary of lookup arguments |
|
114 # but need to support arbitrary queries via Q objects too. |
|
115 >>> Article.objects.complex_filter({'pk': 1}) |
|
116 [<Article: Hello>] |
|
117 >>> Article.objects.complex_filter(Q(pk=1) | Q(pk=2)) |
|
118 [<Article: Hello>, <Article: Goodbye>] |
|
119 """} |
|