| | 1 | """ |
| | 2 | 13. Building complex queries. |
| | 3 | |
| | 4 | To build complex queries involving AND and OR clauses, use the meta.AND |
| | 5 | and meta.OR functions. |
| | 6 | """ |
| | 7 | |
| | 8 | from django.core import meta |
| | 9 | |
| | 10 | class Person(meta.Model): |
| | 11 | fields = ( |
| | 12 | meta.CharField('fname', maxlength=25), |
| | 13 | meta.CharField('lname', maxlength=25), |
| | 14 | meta.IntegerField('age'), |
| | 15 | ) |
| | 16 | def __repr__(self): |
| | 17 | return '%s %s (%s)' % (self.fname, self.lname, self.age) |
| | 18 | |
| | 19 | API_TESTS = """ |
| | 20 | # Make sure meta gets imported; we'll need it later |
| | 21 | >>> from django.core import meta |
| | 22 | |
| | 23 | # Add some people to the system |
| | 24 | >>> p = persons.Person(fname='John', lname='Smith', age=26) |
| | 25 | >>> p.save() |
| | 26 | >>> p = persons.Person(fname='Mary', lname='Smith', age=31) |
| | 27 | >>> p.save() |
| | 28 | >>> p = persons.Person(fname='Betty', lname='Jones', age=30) |
| | 29 | >>> p.save() |
| | 30 | >>> p = persons.Person(fname='Bob', lname='Jones', age=42) |
| | 31 | >>> p.save() |
| | 32 | >>> p = persons.Person(fname='Susan', lname='White', age=70) |
| | 33 | >>> p.save() |
| | 34 | >>> p = persons.Person(fname='James', lname='White', age=65) |
| | 35 | >>> p.save() |
| | 36 | >>> p = persons.Person(fname='Karen', lname='White', age=33) |
| | 37 | >>> p.save() |
| | 38 | |
| | 39 | # Verify that the test data got loaded correctly. |
| | 40 | >>> persons.get_list(order_by=['age']) |
| | 41 | [John Smith (26), Betty Jones (30), Mary Smith (31), Karen White (33), \ |
| | 42 | Bob Jones (42), James White (65), Susan White (70)] |
| | 43 | |
| | 44 | # Search clauses are joined with an AND by default |
| | 45 | >>> persons.get_list(order_by=['age'], lname__exact='Smith') |
| | 46 | [John Smith (26), Mary Smith (31)] |
| | 47 | >>> persons.get_list(order_by=['age'], lname__exact='Smith', age__gte=30) |
| | 48 | [Mary Smith (31)] |
| | 49 | |
| | 50 | # Use "clause=meta.OR" to join with an OR instead |
| | 51 | >>> persons.get_list(order_by=['age'], clause=meta.OR(lname__exact='Smith', age__gte=50)) |
| | 52 | [John Smith (26), Mary Smith (31), James White (65), Susan White (70)] |
| | 53 | |
| | 54 | # You can nest AND clauses inside OR clauses |
| | 55 | >>> persons.get_list(order_by=['age'], clause=meta.OR(lname__exact='Smith', |
| | 56 | ... clause=meta.AND(lname__exact='White', age__lte=65))) |
| | 57 | [John Smith (26), Mary Smith (31), Karen White (33), James White (65)] |
| | 58 | |
| | 59 | # Since Python doesn't let you repeat the same keyword parameter twice in a |
| | 60 | # function call, use clause# (where # is a number) if you want to have |
| | 61 | # multiple AND or OR clauses in a single get_list |
| | 62 | # (Remember that the outer level of clauses is joined by AND) |
| | 63 | >>> persons.get_list(order_by=['age'], clause1=meta.OR(age__lte=30, age__gte=60), |
| | 64 | ... clause2=meta.OR(fname__startswith='B', lname__startswith='W')) |
| | 65 | [Betty Jones (30), James White (65), Susan White (70)] |
| | 66 | """ |