|
1 from django.test import TestCase |
|
2 from django.core.exceptions import FieldError |
|
3 |
|
4 from regressiontests.null_queries.models import * |
|
5 |
|
6 |
|
7 class NullQueriesTests(TestCase): |
|
8 |
|
9 def test_none_as_null(self): |
|
10 """ |
|
11 Regression test for the use of None as a query value. |
|
12 |
|
13 None is interpreted as an SQL NULL, but only in __exact queries. |
|
14 Set up some initial polls and choices |
|
15 """ |
|
16 p1 = Poll(question='Why?') |
|
17 p1.save() |
|
18 c1 = Choice(poll=p1, choice='Because.') |
|
19 c1.save() |
|
20 c2 = Choice(poll=p1, choice='Why Not?') |
|
21 c2.save() |
|
22 |
|
23 # Exact query with value None returns nothing ("is NULL" in sql, |
|
24 # but every 'id' field has a value). |
|
25 self.assertQuerysetEqual(Choice.objects.filter(choice__exact=None), []) |
|
26 |
|
27 # Excluding the previous result returns everything. |
|
28 self.assertQuerysetEqual( |
|
29 Choice.objects.exclude(choice=None).order_by('id'), |
|
30 [ |
|
31 '<Choice: Choice: Because. in poll Q: Why? >', |
|
32 '<Choice: Choice: Why Not? in poll Q: Why? >' |
|
33 ] |
|
34 ) |
|
35 |
|
36 # Valid query, but fails because foo isn't a keyword |
|
37 self.assertRaises(FieldError, Choice.objects.filter, foo__exact=None) |
|
38 |
|
39 # Can't use None on anything other than __exact |
|
40 self.assertRaises(ValueError, Choice.objects.filter, id__gt=None) |
|
41 |
|
42 # Can't use None on anything other than __exact |
|
43 self.assertRaises(ValueError, Choice.objects.filter, foo__gt=None) |
|
44 |
|
45 # Related managers use __exact=None implicitly if the object hasn't been saved. |
|
46 p2 = Poll(question="How?") |
|
47 self.assertEquals(repr(p2.choice_set.all()), '[]') |
|
48 |
|
49 def test_reverse_relations(self): |
|
50 """ |
|
51 Querying across reverse relations and then another relation should |
|
52 insert outer joins correctly so as not to exclude results. |
|
53 """ |
|
54 obj = OuterA.objects.create() |
|
55 self.assertQuerysetEqual( |
|
56 OuterA.objects.filter(inner__second=None), |
|
57 ['<OuterA: OuterA object>'] |
|
58 ) |
|
59 self.assertQuerysetEqual( |
|
60 OuterA.objects.filter(inner__second__data=None), |
|
61 ['<OuterA: OuterA object>'] |
|
62 ) |
|
63 |
|
64 inner_obj = Inner.objects.create(first=obj) |
|
65 self.assertQuerysetEqual( |
|
66 Inner.objects.filter(first__inner__second=None), |
|
67 ['<Inner: Inner object>'] |
|
68 ) |
|
69 |