Ticket #18583: models.py

File models.py, 3.9 KB (added by Rebecca Breu, 12 years ago)
Line 
1from django.db import models, connection
2from django.contrib.auth.models import Group
3
4class A(models.Model):
5 name = models.CharField(max_length=150)
6
7 def __unicode__(self):
8 return self.name
9
10class AGroups(models.Model):
11 a = models.ForeignKey(A, related_name='groups')
12 group = models.ForeignKey(Group)
13
14class B(models.Model):
15 name = models.CharField(max_length=150)
16 a = models.ForeignKey(A)
17
18 def __unicode__(self):
19 return self.name
20
21class C(models.Model):
22 name = models.CharField(max_length=150)
23 b = models.ForeignKey(B)
24
25 def __unicode__(self):
26 return self.name
27
28
29
30def testdata():
31 # Order of creation is important; we need mixed-up IDs
32 a1 = A.objects.create(name='1')
33 a2 = A.objects.create(name='2')
34 a3 = A.objects.create(name='3')
35 b3 = B.objects.create(name='3', a=a3)
36 b1 = B.objects.create(name='1', a=a1)
37 b2 = B.objects.create(name='2', a=a2)
38 c2 = C.objects.create(name='2', b=b2)
39 c3 = C.objects.create(name='3', b=b3)
40 c1 = C.objects.create(name='1', b=b1)
41
42 g1 = Group.objects.create(name='1')
43 AGroups.objects.create(a=a1, group=g1)
44 g2 = Group.objects.create(name='2')
45 AGroups.objects.create(a=a2, group=g2)
46
47
48def testquery():
49 g1 = Group.objects.get(name='1')
50 g2 = Group.objects.get(name='2')
51 print 'all', C.objects.all()
52
53 for gs in [[g1], [g2], [g1, g2], []]:
54 print '==='
55 print 'groups', gs
56 print 'filter', C.objects.filter(b__a__groups__group__in=gs)
57 print 'exclude', C.objects.exclude(b__a__groups__group__in=gs)
58 # What I expect:
59 print (set(C.objects.all()) ==
60 set(C.objects.filter(b__a__groups__group__in=gs)) |
61 set(C.objects.exclude(b__a__groups__group__in=gs)))
62
63 """
64 What I get:
65
66 all [<C: 2>, <C: 3>, <C: 1>]
67 ===
68 groups [<Group: 1>]
69 filter [<C: 1>]
70 exclude [<C: 3>, <C: 1>]
71 False
72 ===
73 groups [<Group: 2>]
74 filter [<C: 2>]
75 exclude [<C: 2>, <C: 1>]
76 False
77 ===
78 groups [<Group: 1>, <Group: 2>]
79 filter [<C: 1>, <C: 2>]
80 exclude [<C: 1>]
81 False
82 ===
83 groups []
84 filter []
85 exclude [<C: 2>, <C: 3>, <C: 1>]
86 True
87 """
88
89def debugquery():
90 g1 = Group.objects.get(name='1')
91 print C.objects.exclude(b__a__groups__group__in=[g1])
92 print connection.queries[-1]['sql']
93
94 """
95 SELECT "books_c"."id", "books_c"."name", "books_c"."b_id" FROM "books_c"
96 INNER JOIN "books_b" ON ("books_c"."b_id" = "books_b"."id")
97 INNER JOIN "books_a" ON ("books_b"."a_id" = "books_a"."id")
98 WHERE NOT (("books_b"."a_id" IN -- should be: "books_b"."id" IN
99 (SELECT U1."id" FROM "books_b" U1
100 INNER JOIN "books_a" U2 ON (U1."a_id" = U2."id")
101 INNER JOIN "books_agroups" U3 ON (U2."id" = U3."a_id")
102 WHERE (U3."group_id" IN (1) AND U1."id" IS NOT NULL))
103 AND "books_a"."id" IS NOT NULL)) LIMIT 21
104 """
105
106 # Slightly different query which should get the same result leads
107 # to the same bug:
108 agroups = AGroups.objects.filter(group__in=[g1])
109 print agroups
110 print C.objects.exclude(b__a__groups__in=agroups)
111 print connection.queries[-1]['sql']
112
113 """
114 SELECT "books_c"."id", "books_c"."name", "books_c"."b_id" FROM "books_c"
115 INNER JOIN "books_b" ON ("books_c"."b_id" = "books_b"."id")
116 INNER JOIN "books_a" ON ("books_b"."a_id" = "books_a"."id")
117 WHERE NOT (("books_b"."a_id" IN -- should be: "books_b"."id" IN
118 (SELECT U1."id" FROM "books_b" U1
119 INNER JOIN "books_a" U2 ON (U1."a_id" = U2."id")
120 INNER JOIN "books_agroups" U3 ON (U2."id" = U3."a_id")
121 WHERE (U3."id" IN (SELECT U0."id" FROM "books_agroups" U0
122 WHERE U0."group_id" IN (1)) AND U1."id" IS NOT NULL))
123 AND "books_a"."id" IS NOT NULL)) LIMIT 21
124 """
125
126 # This works:
127 b_excludes = B.objects.filter(a__groups__group__in=[g1])
128 print C.objects.exclude(b__in=b_excludes)
129 print connection.queries[-1]['sql']
130
Back to Top