tests.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. from django.db.models.signals import post_save, pre_save
  2. from django.test import TestCase
  3. from .models import Account, Employee, Person, Profile, ProxyEmployee
  4. class UpdateOnlyFieldsTests(TestCase):
  5. def test_update_fields_basic(self):
  6. s = Person.objects.create(name='Sara', gender='F')
  7. self.assertEqual(s.gender, 'F')
  8. s.gender = 'M'
  9. s.name = 'Ian'
  10. s.save(update_fields=['name'])
  11. s = Person.objects.get(pk=s.pk)
  12. self.assertEqual(s.gender, 'F')
  13. self.assertEqual(s.name, 'Ian')
  14. def test_update_fields_deferred(self):
  15. s = Person.objects.create(name='Sara', gender='F', pid=22)
  16. self.assertEqual(s.gender, 'F')
  17. s1 = Person.objects.defer("gender", "pid").get(pk=s.pk)
  18. s1.name = "Emily"
  19. s1.gender = "M"
  20. with self.assertNumQueries(1):
  21. s1.save()
  22. s2 = Person.objects.get(pk=s1.pk)
  23. self.assertEqual(s2.name, "Emily")
  24. self.assertEqual(s2.gender, "M")
  25. def test_update_fields_only_1(self):
  26. s = Person.objects.create(name='Sara', gender='F')
  27. self.assertEqual(s.gender, 'F')
  28. s1 = Person.objects.only('name').get(pk=s.pk)
  29. s1.name = "Emily"
  30. s1.gender = "M"
  31. with self.assertNumQueries(1):
  32. s1.save()
  33. s2 = Person.objects.get(pk=s1.pk)
  34. self.assertEqual(s2.name, "Emily")
  35. self.assertEqual(s2.gender, "M")
  36. def test_update_fields_only_2(self):
  37. s = Person.objects.create(name='Sara', gender='F', pid=22)
  38. self.assertEqual(s.gender, 'F')
  39. s1 = Person.objects.only('name').get(pk=s.pk)
  40. s1.name = "Emily"
  41. s1.gender = "M"
  42. with self.assertNumQueries(2):
  43. s1.save(update_fields=['pid'])
  44. s2 = Person.objects.get(pk=s1.pk)
  45. self.assertEqual(s2.name, "Sara")
  46. self.assertEqual(s2.gender, "F")
  47. def test_update_fields_only_repeated(self):
  48. s = Person.objects.create(name='Sara', gender='F')
  49. self.assertEqual(s.gender, 'F')
  50. s1 = Person.objects.only('name').get(pk=s.pk)
  51. s1.gender = 'M'
  52. with self.assertNumQueries(1):
  53. s1.save()
  54. # save() should not fetch deferred fields
  55. s1 = Person.objects.only('name').get(pk=s.pk)
  56. with self.assertNumQueries(1):
  57. s1.save()
  58. def test_update_fields_inheritance_defer(self):
  59. profile_boss = Profile.objects.create(name='Boss', salary=3000)
  60. e1 = Employee.objects.create(name='Sara', gender='F', employee_num=1, profile=profile_boss)
  61. e1 = Employee.objects.only('name').get(pk=e1.pk)
  62. e1.name = 'Linda'
  63. with self.assertNumQueries(1):
  64. e1.save()
  65. self.assertEqual(Employee.objects.get(pk=e1.pk).name, 'Linda')
  66. def test_update_fields_fk_defer(self):
  67. profile_boss = Profile.objects.create(name='Boss', salary=3000)
  68. profile_receptionist = Profile.objects.create(name='Receptionist', salary=1000)
  69. e1 = Employee.objects.create(name='Sara', gender='F', employee_num=1, profile=profile_boss)
  70. e1 = Employee.objects.only('profile').get(pk=e1.pk)
  71. e1.profile = profile_receptionist
  72. with self.assertNumQueries(1):
  73. e1.save()
  74. self.assertEqual(Employee.objects.get(pk=e1.pk).profile, profile_receptionist)
  75. e1.profile_id = profile_boss.pk
  76. with self.assertNumQueries(1):
  77. e1.save()
  78. self.assertEqual(Employee.objects.get(pk=e1.pk).profile, profile_boss)
  79. def test_select_related_only_interaction(self):
  80. profile_boss = Profile.objects.create(name='Boss', salary=3000)
  81. e1 = Employee.objects.create(name='Sara', gender='F', employee_num=1, profile=profile_boss)
  82. e1 = Employee.objects.only('profile__salary').select_related('profile').get(pk=e1.pk)
  83. profile_boss.name = 'Clerk'
  84. profile_boss.salary = 1000
  85. profile_boss.save()
  86. # The loaded salary of 3000 gets saved, the name of 'Clerk' isn't
  87. # overwritten.
  88. with self.assertNumQueries(1):
  89. e1.profile.save()
  90. reloaded_profile = Profile.objects.get(pk=profile_boss.pk)
  91. self.assertEqual(reloaded_profile.name, profile_boss.name)
  92. self.assertEqual(reloaded_profile.salary, 3000)
  93. def test_update_fields_m2m(self):
  94. profile_boss = Profile.objects.create(name='Boss', salary=3000)
  95. e1 = Employee.objects.create(name='Sara', gender='F', employee_num=1, profile=profile_boss)
  96. a1 = Account.objects.create(num=1)
  97. a2 = Account.objects.create(num=2)
  98. e1.accounts.set([a1, a2])
  99. with self.assertRaises(ValueError):
  100. e1.save(update_fields=['accounts'])
  101. def test_update_fields_inheritance(self):
  102. profile_boss = Profile.objects.create(name='Boss', salary=3000)
  103. profile_receptionist = Profile.objects.create(name='Receptionist', salary=1000)
  104. e1 = Employee.objects.create(name='Sara', gender='F', employee_num=1, profile=profile_boss)
  105. e1.name = 'Ian'
  106. e1.gender = 'M'
  107. e1.save(update_fields=['name'])
  108. e2 = Employee.objects.get(pk=e1.pk)
  109. self.assertEqual(e2.name, 'Ian')
  110. self.assertEqual(e2.gender, 'F')
  111. self.assertEqual(e2.profile, profile_boss)
  112. e2.profile = profile_receptionist
  113. e2.name = 'Sara'
  114. e2.save(update_fields=['profile'])
  115. e3 = Employee.objects.get(pk=e1.pk)
  116. self.assertEqual(e3.name, 'Ian')
  117. self.assertEqual(e3.profile, profile_receptionist)
  118. with self.assertNumQueries(1):
  119. e3.profile = profile_boss
  120. e3.save(update_fields=['profile_id'])
  121. e4 = Employee.objects.get(pk=e3.pk)
  122. self.assertEqual(e4.profile, profile_boss)
  123. self.assertEqual(e4.profile_id, profile_boss.pk)
  124. def test_update_fields_inheritance_with_proxy_model(self):
  125. profile_boss = Profile.objects.create(name='Boss', salary=3000)
  126. profile_receptionist = Profile.objects.create(name='Receptionist', salary=1000)
  127. e1 = ProxyEmployee.objects.create(name='Sara', gender='F', employee_num=1, profile=profile_boss)
  128. e1.name = 'Ian'
  129. e1.gender = 'M'
  130. e1.save(update_fields=['name'])
  131. e2 = ProxyEmployee.objects.get(pk=e1.pk)
  132. self.assertEqual(e2.name, 'Ian')
  133. self.assertEqual(e2.gender, 'F')
  134. self.assertEqual(e2.profile, profile_boss)
  135. e2.profile = profile_receptionist
  136. e2.name = 'Sara'
  137. e2.save(update_fields=['profile'])
  138. e3 = ProxyEmployee.objects.get(pk=e1.pk)
  139. self.assertEqual(e3.name, 'Ian')
  140. self.assertEqual(e3.profile, profile_receptionist)
  141. def test_update_fields_signals(self):
  142. p = Person.objects.create(name='Sara', gender='F')
  143. pre_save_data = []
  144. def pre_save_receiver(**kwargs):
  145. pre_save_data.append(kwargs['update_fields'])
  146. pre_save.connect(pre_save_receiver)
  147. post_save_data = []
  148. def post_save_receiver(**kwargs):
  149. post_save_data.append(kwargs['update_fields'])
  150. post_save.connect(post_save_receiver)
  151. p.save(update_fields=['name'])
  152. self.assertEqual(len(pre_save_data), 1)
  153. self.assertEqual(len(pre_save_data[0]), 1)
  154. self.assertIn('name', pre_save_data[0])
  155. self.assertEqual(len(post_save_data), 1)
  156. self.assertEqual(len(post_save_data[0]), 1)
  157. self.assertIn('name', post_save_data[0])
  158. pre_save.disconnect(pre_save_receiver)
  159. post_save.disconnect(post_save_receiver)
  160. def test_update_fields_incorrect_params(self):
  161. s = Person.objects.create(name='Sara', gender='F')
  162. with self.assertRaises(ValueError):
  163. s.save(update_fields=['first_name'])
  164. with self.assertRaises(ValueError):
  165. s.save(update_fields="name")
  166. def test_empty_update_fields(self):
  167. s = Person.objects.create(name='Sara', gender='F')
  168. pre_save_data = []
  169. def pre_save_receiver(**kwargs):
  170. pre_save_data.append(kwargs['update_fields'])
  171. pre_save.connect(pre_save_receiver)
  172. post_save_data = []
  173. def post_save_receiver(**kwargs):
  174. post_save_data.append(kwargs['update_fields'])
  175. post_save.connect(post_save_receiver)
  176. # Save is skipped.
  177. with self.assertNumQueries(0):
  178. s.save(update_fields=[])
  179. # Signals were skipped, too...
  180. self.assertEqual(len(pre_save_data), 0)
  181. self.assertEqual(len(post_save_data), 0)
  182. pre_save.disconnect(pre_save_receiver)
  183. post_save.disconnect(post_save_receiver)
  184. def test_num_queries_inheritance(self):
  185. s = Employee.objects.create(name='Sara', gender='F')
  186. s.employee_num = 1
  187. s.name = 'Emily'
  188. with self.assertNumQueries(1):
  189. s.save(update_fields=['employee_num'])
  190. s = Employee.objects.get(pk=s.pk)
  191. self.assertEqual(s.employee_num, 1)
  192. self.assertEqual(s.name, 'Sara')
  193. s.employee_num = 2
  194. s.name = 'Emily'
  195. with self.assertNumQueries(1):
  196. s.save(update_fields=['name'])
  197. s = Employee.objects.get(pk=s.pk)
  198. self.assertEqual(s.name, 'Emily')
  199. self.assertEqual(s.employee_num, 1)
  200. # A little sanity check that we actually did updates...
  201. self.assertEqual(Employee.objects.count(), 1)
  202. self.assertEqual(Person.objects.count(), 1)
  203. with self.assertNumQueries(2):
  204. s.save(update_fields=['name', 'employee_num'])