mirror of
https://github.com/django/django.git
synced 2025-10-24 14:16:09 +00:00
Refs #33476 -- Reformatted code with Black.
This commit is contained in:
committed by
Mariusz Felisiak
parent
f68fa8b45d
commit
9c19aff7c7
@@ -9,33 +9,39 @@ from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
|
||||
from django.utils.functional import lazy
|
||||
|
||||
from .models import (
|
||||
Author, Book, DefaultPerson, ManualPrimaryKeyTest, Person, Profile,
|
||||
Publisher, Tag, Thing,
|
||||
Author,
|
||||
Book,
|
||||
DefaultPerson,
|
||||
ManualPrimaryKeyTest,
|
||||
Person,
|
||||
Profile,
|
||||
Publisher,
|
||||
Tag,
|
||||
Thing,
|
||||
)
|
||||
|
||||
|
||||
class GetOrCreateTests(TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
Person.objects.create(
|
||||
first_name='John', last_name='Lennon', birthday=date(1940, 10, 9)
|
||||
first_name="John", last_name="Lennon", birthday=date(1940, 10, 9)
|
||||
)
|
||||
|
||||
def test_get_or_create_method_with_get(self):
|
||||
created = Person.objects.get_or_create(
|
||||
first_name="John", last_name="Lennon", defaults={
|
||||
"birthday": date(1940, 10, 9)
|
||||
}
|
||||
first_name="John",
|
||||
last_name="Lennon",
|
||||
defaults={"birthday": date(1940, 10, 9)},
|
||||
)[1]
|
||||
self.assertFalse(created)
|
||||
self.assertEqual(Person.objects.count(), 1)
|
||||
|
||||
def test_get_or_create_method_with_create(self):
|
||||
created = Person.objects.get_or_create(
|
||||
first_name='George', last_name='Harrison', defaults={
|
||||
'birthday': date(1943, 2, 25)
|
||||
}
|
||||
first_name="George",
|
||||
last_name="Harrison",
|
||||
defaults={"birthday": date(1943, 2, 25)},
|
||||
)[1]
|
||||
self.assertTrue(created)
|
||||
self.assertEqual(Person.objects.count(), 2)
|
||||
@@ -46,14 +52,14 @@ class GetOrCreateTests(TestCase):
|
||||
it won't create a Person.
|
||||
"""
|
||||
Person.objects.get_or_create(
|
||||
first_name='George', last_name='Harrison', defaults={
|
||||
'birthday': date(1943, 2, 25)
|
||||
}
|
||||
first_name="George",
|
||||
last_name="Harrison",
|
||||
defaults={"birthday": date(1943, 2, 25)},
|
||||
)
|
||||
created = Person.objects.get_or_create(
|
||||
first_name='George', last_name='Harrison', defaults={
|
||||
'birthday': date(1943, 2, 25)
|
||||
}
|
||||
first_name="George",
|
||||
last_name="Harrison",
|
||||
defaults={"birthday": date(1943, 2, 25)},
|
||||
)[1]
|
||||
|
||||
self.assertFalse(created)
|
||||
@@ -75,8 +81,10 @@ class GetOrCreateTests(TestCase):
|
||||
|
||||
def test_get_or_create_with_model_property_defaults(self):
|
||||
"""Using a property with a setter implemented is allowed."""
|
||||
t, _ = Thing.objects.get_or_create(defaults={'capitalized_name_property': 'annie'}, pk=1)
|
||||
self.assertEqual(t.name, 'Annie')
|
||||
t, _ = Thing.objects.get_or_create(
|
||||
defaults={"capitalized_name_property": "annie"}, pk=1
|
||||
)
|
||||
self.assertEqual(t.name, "Annie")
|
||||
|
||||
def test_get_or_create_on_related_manager(self):
|
||||
p = Publisher.objects.create(name="Acme Publishing")
|
||||
@@ -127,11 +135,15 @@ class GetOrCreateTests(TestCase):
|
||||
self.assertEqual(fred.books.count(), 1)
|
||||
|
||||
# Use the publisher's primary key value instead of a model instance.
|
||||
_, created = ed.books.get_or_create(name='The Great Book of Ed', publisher_id=p.id)
|
||||
_, created = ed.books.get_or_create(
|
||||
name="The Great Book of Ed", publisher_id=p.id
|
||||
)
|
||||
self.assertTrue(created)
|
||||
|
||||
# Try get_or_create again, this time nothing should be created.
|
||||
_, created = ed.books.get_or_create(name='The Great Book of Ed', publisher_id=p.id)
|
||||
_, created = ed.books.get_or_create(
|
||||
name="The Great Book of Ed", publisher_id=p.id
|
||||
)
|
||||
self.assertFalse(created)
|
||||
|
||||
# The publisher should have three books.
|
||||
@@ -143,18 +155,24 @@ class GetOrCreateTests(TestCase):
|
||||
lookup, you need to use 'defaults__exact'.
|
||||
"""
|
||||
obj, created = Person.objects.get_or_create(
|
||||
first_name='George', last_name='Harrison', defaults__exact='testing', defaults={
|
||||
'birthday': date(1943, 2, 25),
|
||||
'defaults': 'testing',
|
||||
}
|
||||
first_name="George",
|
||||
last_name="Harrison",
|
||||
defaults__exact="testing",
|
||||
defaults={
|
||||
"birthday": date(1943, 2, 25),
|
||||
"defaults": "testing",
|
||||
},
|
||||
)
|
||||
self.assertTrue(created)
|
||||
self.assertEqual(obj.defaults, 'testing')
|
||||
self.assertEqual(obj.defaults, "testing")
|
||||
obj2, created = Person.objects.get_or_create(
|
||||
first_name='George', last_name='Harrison', defaults__exact='testing', defaults={
|
||||
'birthday': date(1943, 2, 25),
|
||||
'defaults': 'testing',
|
||||
}
|
||||
first_name="George",
|
||||
last_name="Harrison",
|
||||
defaults__exact="testing",
|
||||
defaults={
|
||||
"birthday": date(1943, 2, 25),
|
||||
"defaults": "testing",
|
||||
},
|
||||
)
|
||||
self.assertFalse(created)
|
||||
self.assertEqual(obj, obj2)
|
||||
@@ -173,23 +191,27 @@ class GetOrCreateTests(TestCase):
|
||||
def test_callable_defaults_not_called(self):
|
||||
def raise_exception():
|
||||
raise AssertionError
|
||||
|
||||
obj, created = Person.objects.get_or_create(
|
||||
first_name="John", last_name="Lennon",
|
||||
first_name="John",
|
||||
last_name="Lennon",
|
||||
defaults={"birthday": lambda: raise_exception()},
|
||||
)
|
||||
|
||||
def test_defaults_not_evaluated_unless_needed(self):
|
||||
"""`defaults` aren't evaluated if the instance isn't created."""
|
||||
|
||||
def raise_exception():
|
||||
raise AssertionError
|
||||
|
||||
obj, created = Person.objects.get_or_create(
|
||||
first_name='John', defaults=lazy(raise_exception, object)(),
|
||||
first_name="John",
|
||||
defaults=lazy(raise_exception, object)(),
|
||||
)
|
||||
self.assertFalse(created)
|
||||
|
||||
|
||||
class GetOrCreateTestsWithManualPKs(TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
ManualPrimaryKeyTest.objects.create(id=1, data="Original")
|
||||
@@ -214,20 +236,20 @@ class GetOrCreateTestsWithManualPKs(TestCase):
|
||||
ManualPrimaryKeyTest.objects.get_or_create(id=1, data="Different")
|
||||
except IntegrityError:
|
||||
formatted_traceback = traceback.format_exc()
|
||||
self.assertIn('obj.save', formatted_traceback)
|
||||
self.assertIn("obj.save", formatted_traceback)
|
||||
|
||||
def test_savepoint_rollback(self):
|
||||
"""
|
||||
The database connection is still usable after a DatabaseError in
|
||||
get_or_create() (#20463).
|
||||
"""
|
||||
Tag.objects.create(text='foo')
|
||||
Tag.objects.create(text="foo")
|
||||
with self.assertRaises(DatabaseError):
|
||||
# pk 123456789 doesn't exist, so the tag object will be created.
|
||||
# Saving triggers a unique constraint violation on 'text'.
|
||||
Tag.objects.get_or_create(pk=123456789, defaults={'text': 'foo'})
|
||||
Tag.objects.get_or_create(pk=123456789, defaults={"text": "foo"})
|
||||
# Tag objects can be created after the error.
|
||||
Tag.objects.create(text='bar')
|
||||
Tag.objects.create(text="bar")
|
||||
|
||||
def test_get_or_create_empty(self):
|
||||
"""
|
||||
@@ -239,7 +261,7 @@ class GetOrCreateTestsWithManualPKs(TestCase):
|
||||
|
||||
class GetOrCreateTransactionTests(TransactionTestCase):
|
||||
|
||||
available_apps = ['get_or_create']
|
||||
available_apps = ["get_or_create"]
|
||||
|
||||
def test_get_or_create_integrityerror(self):
|
||||
"""
|
||||
@@ -256,63 +278,61 @@ class GetOrCreateTransactionTests(TransactionTestCase):
|
||||
|
||||
|
||||
class GetOrCreateThroughManyToMany(TestCase):
|
||||
|
||||
def test_get_get_or_create(self):
|
||||
tag = Tag.objects.create(text='foo')
|
||||
a_thing = Thing.objects.create(name='a')
|
||||
tag = Tag.objects.create(text="foo")
|
||||
a_thing = Thing.objects.create(name="a")
|
||||
a_thing.tags.add(tag)
|
||||
obj, created = a_thing.tags.get_or_create(text='foo')
|
||||
obj, created = a_thing.tags.get_or_create(text="foo")
|
||||
|
||||
self.assertFalse(created)
|
||||
self.assertEqual(obj.pk, tag.pk)
|
||||
|
||||
def test_create_get_or_create(self):
|
||||
a_thing = Thing.objects.create(name='a')
|
||||
obj, created = a_thing.tags.get_or_create(text='foo')
|
||||
a_thing = Thing.objects.create(name="a")
|
||||
obj, created = a_thing.tags.get_or_create(text="foo")
|
||||
|
||||
self.assertTrue(created)
|
||||
self.assertEqual(obj.text, 'foo')
|
||||
self.assertEqual(obj.text, "foo")
|
||||
self.assertIn(obj, a_thing.tags.all())
|
||||
|
||||
def test_something(self):
|
||||
Tag.objects.create(text='foo')
|
||||
a_thing = Thing.objects.create(name='a')
|
||||
Tag.objects.create(text="foo")
|
||||
a_thing = Thing.objects.create(name="a")
|
||||
with self.assertRaises(IntegrityError):
|
||||
a_thing.tags.get_or_create(text='foo')
|
||||
a_thing.tags.get_or_create(text="foo")
|
||||
|
||||
|
||||
class UpdateOrCreateTests(TestCase):
|
||||
|
||||
def test_update(self):
|
||||
Person.objects.create(
|
||||
first_name='John', last_name='Lennon', birthday=date(1940, 10, 9)
|
||||
first_name="John", last_name="Lennon", birthday=date(1940, 10, 9)
|
||||
)
|
||||
p, created = Person.objects.update_or_create(
|
||||
first_name='John', last_name='Lennon', defaults={
|
||||
'birthday': date(1940, 10, 10)
|
||||
}
|
||||
first_name="John",
|
||||
last_name="Lennon",
|
||||
defaults={"birthday": date(1940, 10, 10)},
|
||||
)
|
||||
self.assertFalse(created)
|
||||
self.assertEqual(p.first_name, 'John')
|
||||
self.assertEqual(p.last_name, 'Lennon')
|
||||
self.assertEqual(p.first_name, "John")
|
||||
self.assertEqual(p.last_name, "Lennon")
|
||||
self.assertEqual(p.birthday, date(1940, 10, 10))
|
||||
|
||||
def test_create(self):
|
||||
p, created = Person.objects.update_or_create(
|
||||
first_name='John', last_name='Lennon', defaults={
|
||||
'birthday': date(1940, 10, 10)
|
||||
}
|
||||
first_name="John",
|
||||
last_name="Lennon",
|
||||
defaults={"birthday": date(1940, 10, 10)},
|
||||
)
|
||||
self.assertTrue(created)
|
||||
self.assertEqual(p.first_name, 'John')
|
||||
self.assertEqual(p.last_name, 'Lennon')
|
||||
self.assertEqual(p.first_name, "John")
|
||||
self.assertEqual(p.last_name, "Lennon")
|
||||
self.assertEqual(p.birthday, date(1940, 10, 10))
|
||||
|
||||
def test_create_twice(self):
|
||||
params = {
|
||||
'first_name': 'John',
|
||||
'last_name': 'Lennon',
|
||||
'birthday': date(1940, 10, 10),
|
||||
"first_name": "John",
|
||||
"last_name": "Lennon",
|
||||
"birthday": date(1940, 10, 10),
|
||||
}
|
||||
Person.objects.update_or_create(**params)
|
||||
# If we execute the exact same statement, it won't create a Person.
|
||||
@@ -345,8 +365,10 @@ class UpdateOrCreateTests(TestCase):
|
||||
|
||||
def test_update_or_create_with_model_property_defaults(self):
|
||||
"""Using a property with a setter implemented is allowed."""
|
||||
t, _ = Thing.objects.get_or_create(defaults={'capitalized_name_property': 'annie'}, pk=1)
|
||||
self.assertEqual(t.name, 'Annie')
|
||||
t, _ = Thing.objects.get_or_create(
|
||||
defaults={"capitalized_name_property": "annie"}, pk=1
|
||||
)
|
||||
self.assertEqual(t.name, "Annie")
|
||||
|
||||
def test_error_contains_full_traceback(self):
|
||||
"""
|
||||
@@ -359,7 +381,7 @@ class UpdateOrCreateTests(TestCase):
|
||||
ManualPrimaryKeyTest.objects.update_or_create(id=1, data="Different")
|
||||
except IntegrityError:
|
||||
formatted_traceback = traceback.format_exc()
|
||||
self.assertIn('obj.save', formatted_traceback)
|
||||
self.assertIn("obj.save", formatted_traceback)
|
||||
|
||||
def test_create_with_related_manager(self):
|
||||
"""
|
||||
@@ -380,7 +402,7 @@ class UpdateOrCreateTests(TestCase):
|
||||
book = Book.objects.create(name="The Book of Ed & Fred", publisher=p)
|
||||
self.assertEqual(p.books.count(), 1)
|
||||
name = "The Book of Django"
|
||||
book, created = p.books.update_or_create(defaults={'name': name}, id=book.id)
|
||||
book, created = p.books.update_or_create(defaults={"name": name}, id=book.id)
|
||||
self.assertFalse(created)
|
||||
self.assertEqual(book.name, name)
|
||||
self.assertEqual(p.books.count(), 1)
|
||||
@@ -392,7 +414,9 @@ class UpdateOrCreateTests(TestCase):
|
||||
"""
|
||||
p = Publisher.objects.create(name="Acme Publishing")
|
||||
author = Author.objects.create(name="Ted")
|
||||
book, created = author.books.update_or_create(name="The Book of Ed & Fred", publisher=p)
|
||||
book, created = author.books.update_or_create(
|
||||
name="The Book of Ed & Fred", publisher=p
|
||||
)
|
||||
self.assertTrue(created)
|
||||
self.assertEqual(author.books.count(), 1)
|
||||
|
||||
@@ -407,7 +431,9 @@ class UpdateOrCreateTests(TestCase):
|
||||
book.authors.add(author)
|
||||
self.assertEqual(author.books.count(), 1)
|
||||
name = "The Book of Django"
|
||||
book, created = author.books.update_or_create(defaults={'name': name}, id=book.id)
|
||||
book, created = author.books.update_or_create(
|
||||
defaults={"name": name}, id=book.id
|
||||
)
|
||||
self.assertFalse(created)
|
||||
self.assertEqual(book.name, name)
|
||||
self.assertEqual(author.books.count(), 1)
|
||||
@@ -418,73 +444,83 @@ class UpdateOrCreateTests(TestCase):
|
||||
lookup, you need to use 'defaults__exact'.
|
||||
"""
|
||||
obj, created = Person.objects.update_or_create(
|
||||
first_name='George', last_name='Harrison', defaults__exact='testing', defaults={
|
||||
'birthday': date(1943, 2, 25),
|
||||
'defaults': 'testing',
|
||||
}
|
||||
first_name="George",
|
||||
last_name="Harrison",
|
||||
defaults__exact="testing",
|
||||
defaults={
|
||||
"birthday": date(1943, 2, 25),
|
||||
"defaults": "testing",
|
||||
},
|
||||
)
|
||||
self.assertTrue(created)
|
||||
self.assertEqual(obj.defaults, 'testing')
|
||||
self.assertEqual(obj.defaults, "testing")
|
||||
obj, created = Person.objects.update_or_create(
|
||||
first_name='George', last_name='Harrison', defaults__exact='testing', defaults={
|
||||
'birthday': date(1943, 2, 25),
|
||||
'defaults': 'another testing',
|
||||
}
|
||||
first_name="George",
|
||||
last_name="Harrison",
|
||||
defaults__exact="testing",
|
||||
defaults={
|
||||
"birthday": date(1943, 2, 25),
|
||||
"defaults": "another testing",
|
||||
},
|
||||
)
|
||||
self.assertFalse(created)
|
||||
self.assertEqual(obj.defaults, 'another testing')
|
||||
self.assertEqual(obj.defaults, "another testing")
|
||||
|
||||
def test_create_callable_default(self):
|
||||
obj, created = Person.objects.update_or_create(
|
||||
first_name='George', last_name='Harrison',
|
||||
defaults={'birthday': lambda: date(1943, 2, 25)},
|
||||
first_name="George",
|
||||
last_name="Harrison",
|
||||
defaults={"birthday": lambda: date(1943, 2, 25)},
|
||||
)
|
||||
self.assertIs(created, True)
|
||||
self.assertEqual(obj.birthday, date(1943, 2, 25))
|
||||
|
||||
def test_update_callable_default(self):
|
||||
Person.objects.update_or_create(
|
||||
first_name='George', last_name='Harrison', birthday=date(1942, 2, 25),
|
||||
first_name="George",
|
||||
last_name="Harrison",
|
||||
birthday=date(1942, 2, 25),
|
||||
)
|
||||
obj, created = Person.objects.update_or_create(
|
||||
first_name='George',
|
||||
defaults={'last_name': lambda: 'NotHarrison'},
|
||||
first_name="George",
|
||||
defaults={"last_name": lambda: "NotHarrison"},
|
||||
)
|
||||
self.assertIs(created, False)
|
||||
self.assertEqual(obj.last_name, 'NotHarrison')
|
||||
self.assertEqual(obj.last_name, "NotHarrison")
|
||||
|
||||
def test_defaults_not_evaluated_unless_needed(self):
|
||||
"""`defaults` aren't evaluated if the instance isn't created."""
|
||||
Person.objects.create(
|
||||
first_name='John', last_name='Lennon', birthday=date(1940, 10, 9)
|
||||
first_name="John", last_name="Lennon", birthday=date(1940, 10, 9)
|
||||
)
|
||||
|
||||
def raise_exception():
|
||||
raise AssertionError
|
||||
|
||||
obj, created = Person.objects.get_or_create(
|
||||
first_name='John', defaults=lazy(raise_exception, object)(),
|
||||
first_name="John",
|
||||
defaults=lazy(raise_exception, object)(),
|
||||
)
|
||||
self.assertFalse(created)
|
||||
|
||||
|
||||
class UpdateOrCreateTestsWithManualPKs(TestCase):
|
||||
|
||||
def test_create_with_duplicate_primary_key(self):
|
||||
"""
|
||||
If an existing primary key is specified with different values for other
|
||||
fields, then IntegrityError is raised and data isn't updated.
|
||||
"""
|
||||
ManualPrimaryKeyTest.objects.create(id=1, data='Original')
|
||||
ManualPrimaryKeyTest.objects.create(id=1, data="Original")
|
||||
with self.assertRaises(IntegrityError):
|
||||
ManualPrimaryKeyTest.objects.update_or_create(id=1, data='Different')
|
||||
self.assertEqual(ManualPrimaryKeyTest.objects.get(id=1).data, 'Original')
|
||||
ManualPrimaryKeyTest.objects.update_or_create(id=1, data="Different")
|
||||
self.assertEqual(ManualPrimaryKeyTest.objects.get(id=1).data, "Original")
|
||||
|
||||
|
||||
class UpdateOrCreateTransactionTests(TransactionTestCase):
|
||||
available_apps = ['get_or_create']
|
||||
available_apps = ["get_or_create"]
|
||||
|
||||
@skipUnlessDBFeature('has_select_for_update')
|
||||
@skipUnlessDBFeature('supports_transactions')
|
||||
@skipUnlessDBFeature("has_select_for_update")
|
||||
@skipUnlessDBFeature("supports_transactions")
|
||||
def test_updates_in_transaction(self):
|
||||
"""
|
||||
Objects are selected and updated in a transaction to avoid race
|
||||
@@ -493,16 +529,16 @@ class UpdateOrCreateTransactionTests(TransactionTestCase):
|
||||
while it holds the lock. The updated field isn't a field in 'defaults',
|
||||
so update_or_create() shouldn't have an effect on it.
|
||||
"""
|
||||
lock_status = {'has_grabbed_lock': False}
|
||||
lock_status = {"has_grabbed_lock": False}
|
||||
|
||||
def birthday_sleep():
|
||||
lock_status['has_grabbed_lock'] = True
|
||||
lock_status["has_grabbed_lock"] = True
|
||||
time.sleep(0.5)
|
||||
return date(1940, 10, 10)
|
||||
|
||||
def update_birthday_slowly():
|
||||
Person.objects.update_or_create(
|
||||
first_name='John', defaults={'birthday': birthday_sleep}
|
||||
first_name="John", defaults={"birthday": birthday_sleep}
|
||||
)
|
||||
# Avoid leaking connection for Oracle
|
||||
connection.close()
|
||||
@@ -511,11 +547,13 @@ class UpdateOrCreateTransactionTests(TransactionTestCase):
|
||||
# timeout after ~0.5 seconds
|
||||
for i in range(20):
|
||||
time.sleep(0.025)
|
||||
if lock_status['has_grabbed_lock']:
|
||||
if lock_status["has_grabbed_lock"]:
|
||||
return True
|
||||
return False
|
||||
|
||||
Person.objects.create(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
|
||||
Person.objects.create(
|
||||
first_name="John", last_name="Lennon", birthday=date(1940, 10, 9)
|
||||
)
|
||||
|
||||
# update_or_create in a separate thread
|
||||
t = Thread(target=update_birthday_slowly)
|
||||
@@ -523,22 +561,22 @@ class UpdateOrCreateTransactionTests(TransactionTestCase):
|
||||
t.start()
|
||||
|
||||
if not lock_wait():
|
||||
self.skipTest('Database took too long to lock the row')
|
||||
self.skipTest("Database took too long to lock the row")
|
||||
|
||||
# Update during lock
|
||||
Person.objects.filter(first_name='John').update(last_name='NotLennon')
|
||||
Person.objects.filter(first_name="John").update(last_name="NotLennon")
|
||||
after_update = datetime.now()
|
||||
|
||||
# Wait for thread to finish
|
||||
t.join()
|
||||
|
||||
# The update remains and it blocked.
|
||||
updated_person = Person.objects.get(first_name='John')
|
||||
updated_person = Person.objects.get(first_name="John")
|
||||
self.assertGreater(after_update - before_start, timedelta(seconds=0.5))
|
||||
self.assertEqual(updated_person.last_name, 'NotLennon')
|
||||
self.assertEqual(updated_person.last_name, "NotLennon")
|
||||
|
||||
@skipUnlessDBFeature('has_select_for_update')
|
||||
@skipUnlessDBFeature('supports_transactions')
|
||||
@skipUnlessDBFeature("has_select_for_update")
|
||||
@skipUnlessDBFeature("supports_transactions")
|
||||
def test_creation_in_transaction(self):
|
||||
"""
|
||||
Objects are selected and updated in a transaction to avoid race
|
||||
@@ -550,16 +588,18 @@ class UpdateOrCreateTransactionTests(TransactionTestCase):
|
||||
can update while it holds the lock. The updated field isn't a field in
|
||||
'defaults', so update_or_create() shouldn't have an effect on it.
|
||||
"""
|
||||
lock_status = {'lock_count': 0}
|
||||
lock_status = {"lock_count": 0}
|
||||
|
||||
def birthday_sleep():
|
||||
lock_status['lock_count'] += 1
|
||||
lock_status["lock_count"] += 1
|
||||
time.sleep(0.5)
|
||||
return date(1940, 10, 10)
|
||||
|
||||
def update_birthday_slowly():
|
||||
try:
|
||||
Person.objects.update_or_create(first_name='John', defaults={'birthday': birthday_sleep})
|
||||
Person.objects.update_or_create(
|
||||
first_name="John", defaults={"birthday": birthday_sleep}
|
||||
)
|
||||
finally:
|
||||
# Avoid leaking connection for Oracle
|
||||
connection.close()
|
||||
@@ -568,9 +608,9 @@ class UpdateOrCreateTransactionTests(TransactionTestCase):
|
||||
# timeout after ~0.5 seconds
|
||||
for i in range(20):
|
||||
time.sleep(0.025)
|
||||
if lock_status['lock_count'] == expected_lock_count:
|
||||
if lock_status["lock_count"] == expected_lock_count:
|
||||
return True
|
||||
self.skipTest('Database took too long to lock the row')
|
||||
self.skipTest("Database took too long to lock the row")
|
||||
|
||||
# update_or_create in a separate thread.
|
||||
t = Thread(target=update_birthday_slowly)
|
||||
@@ -579,53 +619,67 @@ class UpdateOrCreateTransactionTests(TransactionTestCase):
|
||||
lock_wait(1)
|
||||
# Create object *after* initial attempt by update_or_create to get obj
|
||||
# but before creation attempt.
|
||||
Person.objects.create(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
|
||||
Person.objects.create(
|
||||
first_name="John", last_name="Lennon", birthday=date(1940, 10, 9)
|
||||
)
|
||||
lock_wait(2)
|
||||
# At this point, the thread is pausing for 0.5 seconds, so now attempt
|
||||
# to modify object before update_or_create() calls save(). This should
|
||||
# be blocked until after the save().
|
||||
Person.objects.filter(first_name='John').update(last_name='NotLennon')
|
||||
Person.objects.filter(first_name="John").update(last_name="NotLennon")
|
||||
after_update = datetime.now()
|
||||
# Wait for thread to finish
|
||||
t.join()
|
||||
# Check call to update_or_create() succeeded and the subsequent
|
||||
# (blocked) call to update().
|
||||
updated_person = Person.objects.get(first_name='John')
|
||||
self.assertEqual(updated_person.birthday, date(1940, 10, 10)) # set by update_or_create()
|
||||
self.assertEqual(updated_person.last_name, 'NotLennon') # set by update()
|
||||
updated_person = Person.objects.get(first_name="John")
|
||||
self.assertEqual(
|
||||
updated_person.birthday, date(1940, 10, 10)
|
||||
) # set by update_or_create()
|
||||
self.assertEqual(updated_person.last_name, "NotLennon") # set by update()
|
||||
self.assertGreater(after_update - before_start, timedelta(seconds=1))
|
||||
|
||||
|
||||
class InvalidCreateArgumentsTests(TransactionTestCase):
|
||||
available_apps = ['get_or_create']
|
||||
available_apps = ["get_or_create"]
|
||||
msg = "Invalid field name(s) for model Thing: 'nonexistent'."
|
||||
bad_field_msg = "Cannot resolve keyword 'nonexistent' into field. Choices are: id, name, tags"
|
||||
bad_field_msg = (
|
||||
"Cannot resolve keyword 'nonexistent' into field. Choices are: id, name, tags"
|
||||
)
|
||||
|
||||
def test_get_or_create_with_invalid_defaults(self):
|
||||
with self.assertRaisesMessage(FieldError, self.msg):
|
||||
Thing.objects.get_or_create(name='a', defaults={'nonexistent': 'b'})
|
||||
Thing.objects.get_or_create(name="a", defaults={"nonexistent": "b"})
|
||||
|
||||
def test_get_or_create_with_invalid_kwargs(self):
|
||||
with self.assertRaisesMessage(FieldError, self.bad_field_msg):
|
||||
Thing.objects.get_or_create(name='a', nonexistent='b')
|
||||
Thing.objects.get_or_create(name="a", nonexistent="b")
|
||||
|
||||
def test_update_or_create_with_invalid_defaults(self):
|
||||
with self.assertRaisesMessage(FieldError, self.msg):
|
||||
Thing.objects.update_or_create(name='a', defaults={'nonexistent': 'b'})
|
||||
Thing.objects.update_or_create(name="a", defaults={"nonexistent": "b"})
|
||||
|
||||
def test_update_or_create_with_invalid_kwargs(self):
|
||||
with self.assertRaisesMessage(FieldError, self.bad_field_msg):
|
||||
Thing.objects.update_or_create(name='a', nonexistent='b')
|
||||
Thing.objects.update_or_create(name="a", nonexistent="b")
|
||||
|
||||
def test_multiple_invalid_fields(self):
|
||||
with self.assertRaisesMessage(FieldError, self.bad_field_msg):
|
||||
Thing.objects.update_or_create(name='a', nonexistent='b', defaults={'invalid': 'c'})
|
||||
Thing.objects.update_or_create(
|
||||
name="a", nonexistent="b", defaults={"invalid": "c"}
|
||||
)
|
||||
|
||||
def test_property_attribute_without_setter_defaults(self):
|
||||
with self.assertRaisesMessage(FieldError, "Invalid field name(s) for model Thing: 'name_in_all_caps'"):
|
||||
Thing.objects.update_or_create(name='a', defaults={'name_in_all_caps': 'FRANK'})
|
||||
with self.assertRaisesMessage(
|
||||
FieldError, "Invalid field name(s) for model Thing: 'name_in_all_caps'"
|
||||
):
|
||||
Thing.objects.update_or_create(
|
||||
name="a", defaults={"name_in_all_caps": "FRANK"}
|
||||
)
|
||||
|
||||
def test_property_attribute_without_setter_kwargs(self):
|
||||
msg = "Cannot resolve keyword 'name_in_all_caps' into field. Choices are: id, name, tags"
|
||||
with self.assertRaisesMessage(FieldError, msg):
|
||||
Thing.objects.update_or_create(name_in_all_caps='FRANK', defaults={'name': 'Frank'})
|
||||
Thing.objects.update_or_create(
|
||||
name_in_all_caps="FRANK", defaults={"name": "Frank"}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user