tests.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.db import transaction, IntegrityError
  4. from django.test import TestCase, skipIfDBFeature
  5. from django.utils import six
  6. from .models import Employee, Business, Bar, Foo
  7. class CustomPKTests(TestCase):
  8. def test_custom_pk(self):
  9. dan = Employee.objects.create(
  10. employee_code=123, first_name="Dan", last_name="Jones"
  11. )
  12. self.assertQuerysetEqual(
  13. Employee.objects.all(), [
  14. "Dan Jones",
  15. ],
  16. six.text_type
  17. )
  18. fran = Employee.objects.create(
  19. employee_code=456, first_name="Fran", last_name="Bones"
  20. )
  21. self.assertQuerysetEqual(
  22. Employee.objects.all(), [
  23. "Fran Bones",
  24. "Dan Jones",
  25. ],
  26. six.text_type
  27. )
  28. self.assertEqual(Employee.objects.get(pk=123), dan)
  29. self.assertEqual(Employee.objects.get(pk=456), fran)
  30. self.assertRaises(Employee.DoesNotExist,
  31. lambda: Employee.objects.get(pk=42)
  32. )
  33. # Use the name of the primary key, rather than pk.
  34. self.assertEqual(Employee.objects.get(employee_code=123), dan)
  35. # pk can be used as a substitute for the primary key.
  36. self.assertQuerysetEqual(
  37. Employee.objects.filter(pk__in=[123, 456]), [
  38. "Fran Bones",
  39. "Dan Jones",
  40. ],
  41. six.text_type
  42. )
  43. # The primary key can be accessed via the pk property on the model.
  44. e = Employee.objects.get(pk=123)
  45. self.assertEqual(e.pk, 123)
  46. # Or we can use the real attribute name for the primary key:
  47. self.assertEqual(e.employee_code, 123)
  48. # Fran got married and changed her last name.
  49. fran = Employee.objects.get(pk=456)
  50. fran.last_name = "Jones"
  51. fran.save()
  52. self.assertQuerysetEqual(
  53. Employee.objects.filter(last_name="Jones"), [
  54. "Dan Jones",
  55. "Fran Jones",
  56. ],
  57. six.text_type
  58. )
  59. emps = Employee.objects.in_bulk([123, 456])
  60. self.assertEqual(emps[123], dan)
  61. b = Business.objects.create(name="Sears")
  62. b.employees.add(dan, fran)
  63. self.assertQuerysetEqual(
  64. b.employees.all(), [
  65. "Dan Jones",
  66. "Fran Jones",
  67. ],
  68. six.text_type
  69. )
  70. self.assertQuerysetEqual(
  71. fran.business_set.all(), [
  72. "Sears",
  73. ],
  74. lambda b: b.name
  75. )
  76. self.assertEqual(Business.objects.in_bulk(["Sears"]), {
  77. "Sears": b,
  78. })
  79. self.assertQuerysetEqual(
  80. Business.objects.filter(name="Sears"), [
  81. "Sears"
  82. ],
  83. lambda b: b.name
  84. )
  85. self.assertQuerysetEqual(
  86. Business.objects.filter(pk="Sears"), [
  87. "Sears",
  88. ],
  89. lambda b: b.name
  90. )
  91. # Queries across tables, involving primary key
  92. self.assertQuerysetEqual(
  93. Employee.objects.filter(business__name="Sears"), [
  94. "Dan Jones",
  95. "Fran Jones",
  96. ],
  97. six.text_type,
  98. )
  99. self.assertQuerysetEqual(
  100. Employee.objects.filter(business__pk="Sears"), [
  101. "Dan Jones",
  102. "Fran Jones",
  103. ],
  104. six.text_type,
  105. )
  106. self.assertQuerysetEqual(
  107. Business.objects.filter(employees__employee_code=123), [
  108. "Sears",
  109. ],
  110. lambda b: b.name
  111. )
  112. self.assertQuerysetEqual(
  113. Business.objects.filter(employees__pk=123), [
  114. "Sears",
  115. ],
  116. lambda b: b.name,
  117. )
  118. self.assertQuerysetEqual(
  119. Business.objects.filter(employees__first_name__startswith="Fran"), [
  120. "Sears",
  121. ],
  122. lambda b: b.name
  123. )
  124. def test_unicode_pk(self):
  125. # Primary key may be unicode string
  126. Business.objects.create(name='jaźń')
  127. def test_unique_pk(self):
  128. # The primary key must also obviously be unique, so trying to create a
  129. # new object with the same primary key will fail.
  130. Employee.objects.create(
  131. employee_code=123, first_name="Frank", last_name="Jones"
  132. )
  133. with self.assertRaises(IntegrityError):
  134. with transaction.atomic():
  135. Employee.objects.create(employee_code=123, first_name="Fred", last_name="Jones")
  136. def test_custom_field_pk(self):
  137. # Regression for #10785 -- Custom fields can be used for primary keys.
  138. new_bar = Bar.objects.create()
  139. new_foo = Foo.objects.create(bar=new_bar)
  140. f = Foo.objects.get(bar=new_bar.pk)
  141. self.assertEqual(f, new_foo)
  142. self.assertEqual(f.bar, new_bar)
  143. f = Foo.objects.get(bar=new_bar)
  144. self.assertEqual(f, new_foo),
  145. self.assertEqual(f.bar, new_bar)
  146. # SQLite lets objects be saved with an empty primary key, even though an
  147. # integer is expected. So we can't check for an error being raised in that
  148. # case for SQLite. Remove it from the suite for this next bit.
  149. @skipIfDBFeature('supports_unspecified_pk')
  150. def test_required_pk(self):
  151. # The primary key must be specified, so an error is raised if you
  152. # try to create an object without it.
  153. with self.assertRaises(IntegrityError):
  154. with transaction.atomic():
  155. Employee.objects.create(first_name="Tom", last_name="Smith")