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