test_tuple_lookups.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. import unittest
  2. from django.db import NotSupportedError, connection
  3. from django.test import TestCase
  4. from .models import Contact, Customer
  5. class TupleLookupsTests(TestCase):
  6. @classmethod
  7. def setUpTestData(cls):
  8. super().setUpTestData()
  9. cls.customer_1 = Customer.objects.create(customer_id=1, company="a")
  10. cls.customer_2 = Customer.objects.create(customer_id=1, company="b")
  11. cls.customer_3 = Customer.objects.create(customer_id=2, company="c")
  12. cls.customer_4 = Customer.objects.create(customer_id=3, company="d")
  13. cls.customer_5 = Customer.objects.create(customer_id=1, company="e")
  14. cls.contact_1 = Contact.objects.create(customer=cls.customer_1)
  15. cls.contact_2 = Contact.objects.create(customer=cls.customer_1)
  16. cls.contact_3 = Contact.objects.create(customer=cls.customer_2)
  17. cls.contact_4 = Contact.objects.create(customer=cls.customer_3)
  18. cls.contact_5 = Contact.objects.create(customer=cls.customer_1)
  19. cls.contact_6 = Contact.objects.create(customer=cls.customer_5)
  20. def test_exact(self):
  21. test_cases = (
  22. (self.customer_1, (self.contact_1, self.contact_2, self.contact_5)),
  23. (self.customer_2, (self.contact_3,)),
  24. (self.customer_3, (self.contact_4,)),
  25. (self.customer_4, ()),
  26. (self.customer_5, (self.contact_6,)),
  27. )
  28. for customer, contacts in test_cases:
  29. with self.subTest(customer=customer, contacts=contacts):
  30. self.assertSequenceEqual(
  31. Contact.objects.filter(customer=customer).order_by("id"), contacts
  32. )
  33. def test_exact_subquery(self):
  34. with self.assertRaisesMessage(
  35. NotSupportedError, "'exact' doesn't support multi-column subqueries."
  36. ):
  37. subquery = Customer.objects.filter(id=self.customer_1.id)[:1]
  38. self.assertSequenceEqual(
  39. Contact.objects.filter(customer=subquery).order_by("id"), ()
  40. )
  41. def test_in(self):
  42. cust_1, cust_2, cust_3, cust_4, cust_5 = (
  43. self.customer_1,
  44. self.customer_2,
  45. self.customer_3,
  46. self.customer_4,
  47. self.customer_5,
  48. )
  49. c1, c2, c3, c4, c5, c6 = (
  50. self.contact_1,
  51. self.contact_2,
  52. self.contact_3,
  53. self.contact_4,
  54. self.contact_5,
  55. self.contact_6,
  56. )
  57. test_cases = (
  58. ((), ()),
  59. ((cust_1,), (c1, c2, c5)),
  60. ((cust_1, cust_2), (c1, c2, c3, c5)),
  61. ((cust_1, cust_2, cust_3), (c1, c2, c3, c4, c5)),
  62. ((cust_1, cust_2, cust_3, cust_4), (c1, c2, c3, c4, c5)),
  63. ((cust_1, cust_2, cust_3, cust_4, cust_5), (c1, c2, c3, c4, c5, c6)),
  64. )
  65. for contacts, customers in test_cases:
  66. with self.subTest(contacts=contacts, customers=customers):
  67. self.assertSequenceEqual(
  68. Contact.objects.filter(customer__in=contacts).order_by("id"),
  69. customers,
  70. )
  71. @unittest.skipIf(
  72. connection.vendor == "mysql",
  73. "MySQL doesn't support LIMIT & IN/ALL/ANY/SOME subquery",
  74. )
  75. def test_in_subquery(self):
  76. subquery = Customer.objects.filter(id=self.customer_1.id)[:1]
  77. self.assertSequenceEqual(
  78. Contact.objects.filter(customer__in=subquery).order_by("id"),
  79. (self.contact_1, self.contact_2, self.contact_5),
  80. )
  81. def test_lt(self):
  82. c1, c2, c3, c4, c5, c6 = (
  83. self.contact_1,
  84. self.contact_2,
  85. self.contact_3,
  86. self.contact_4,
  87. self.contact_5,
  88. self.contact_6,
  89. )
  90. test_cases = (
  91. (self.customer_1, ()),
  92. (self.customer_2, (c1, c2, c5)),
  93. (self.customer_5, (c1, c2, c3, c5)),
  94. (self.customer_3, (c1, c2, c3, c5, c6)),
  95. (self.customer_4, (c1, c2, c3, c4, c5, c6)),
  96. )
  97. for customer, contacts in test_cases:
  98. with self.subTest(customer=customer, contacts=contacts):
  99. self.assertSequenceEqual(
  100. Contact.objects.filter(customer__lt=customer).order_by("id"),
  101. contacts,
  102. )
  103. def test_lt_subquery(self):
  104. with self.assertRaisesMessage(
  105. NotSupportedError, "'lt' doesn't support multi-column subqueries."
  106. ):
  107. subquery = Customer.objects.filter(id=self.customer_1.id)[:1]
  108. self.assertSequenceEqual(
  109. Contact.objects.filter(customer__lt=subquery).order_by("id"), ()
  110. )
  111. def test_lte(self):
  112. c1, c2, c3, c4, c5, c6 = (
  113. self.contact_1,
  114. self.contact_2,
  115. self.contact_3,
  116. self.contact_4,
  117. self.contact_5,
  118. self.contact_6,
  119. )
  120. test_cases = (
  121. (self.customer_1, (c1, c2, c5)),
  122. (self.customer_2, (c1, c2, c3, c5)),
  123. (self.customer_5, (c1, c2, c3, c5, c6)),
  124. (self.customer_3, (c1, c2, c3, c4, c5, c6)),
  125. (self.customer_4, (c1, c2, c3, c4, c5, c6)),
  126. )
  127. for customer, contacts in test_cases:
  128. with self.subTest(customer=customer, contacts=contacts):
  129. self.assertSequenceEqual(
  130. Contact.objects.filter(customer__lte=customer).order_by("id"),
  131. contacts,
  132. )
  133. def test_lte_subquery(self):
  134. with self.assertRaisesMessage(
  135. NotSupportedError, "'lte' doesn't support multi-column subqueries."
  136. ):
  137. subquery = Customer.objects.filter(id=self.customer_1.id)[:1]
  138. self.assertSequenceEqual(
  139. Contact.objects.filter(customer__lte=subquery).order_by("id"), ()
  140. )
  141. def test_gt(self):
  142. test_cases = (
  143. (self.customer_1, (self.contact_3, self.contact_4, self.contact_6)),
  144. (self.customer_2, (self.contact_4, self.contact_6)),
  145. (self.customer_5, (self.contact_4,)),
  146. (self.customer_3, ()),
  147. (self.customer_4, ()),
  148. )
  149. for customer, contacts in test_cases:
  150. with self.subTest(customer=customer, contacts=contacts):
  151. self.assertSequenceEqual(
  152. Contact.objects.filter(customer__gt=customer).order_by("id"),
  153. contacts,
  154. )
  155. def test_gt_subquery(self):
  156. with self.assertRaisesMessage(
  157. NotSupportedError, "'gt' doesn't support multi-column subqueries."
  158. ):
  159. subquery = Customer.objects.filter(id=self.customer_1.id)[:1]
  160. self.assertSequenceEqual(
  161. Contact.objects.filter(customer__gt=subquery).order_by("id"), ()
  162. )
  163. def test_gte(self):
  164. c1, c2, c3, c4, c5, c6 = (
  165. self.contact_1,
  166. self.contact_2,
  167. self.contact_3,
  168. self.contact_4,
  169. self.contact_5,
  170. self.contact_6,
  171. )
  172. test_cases = (
  173. (self.customer_1, (c1, c2, c3, c4, c5, c6)),
  174. (self.customer_2, (c3, c4, c6)),
  175. (self.customer_5, (c4, c6)),
  176. (self.customer_3, (c4,)),
  177. (self.customer_4, ()),
  178. )
  179. for customer, contacts in test_cases:
  180. with self.subTest(customer=customer, contacts=contacts):
  181. self.assertSequenceEqual(
  182. Contact.objects.filter(customer__gte=customer).order_by("pk"),
  183. contacts,
  184. )
  185. def test_gte_subquery(self):
  186. with self.assertRaisesMessage(
  187. NotSupportedError, "'gte' doesn't support multi-column subqueries."
  188. ):
  189. subquery = Customer.objects.filter(id=self.customer_1.id)[:1]
  190. self.assertSequenceEqual(
  191. Contact.objects.filter(customer__gte=subquery).order_by("id"), ()
  192. )
  193. def test_isnull(self):
  194. with self.subTest("customer__isnull=True"):
  195. self.assertSequenceEqual(
  196. Contact.objects.filter(customer__isnull=True).order_by("id"),
  197. (),
  198. )
  199. with self.subTest("customer__isnull=False"):
  200. self.assertSequenceEqual(
  201. Contact.objects.filter(customer__isnull=False).order_by("id"),
  202. (
  203. self.contact_1,
  204. self.contact_2,
  205. self.contact_3,
  206. self.contact_4,
  207. self.contact_5,
  208. self.contact_6,
  209. ),
  210. )
  211. def test_isnull_subquery(self):
  212. with self.assertRaisesMessage(
  213. NotSupportedError, "'isnull' doesn't support multi-column subqueries."
  214. ):
  215. subquery = Customer.objects.filter(id=0)[:1]
  216. self.assertSequenceEqual(
  217. Contact.objects.filter(customer__isnull=subquery).order_by("id"), ()
  218. )