From 6272d2f155adb4f32ef129d57e9eb5493ebde6ed Mon Sep 17 00:00:00 2001 From: Karol Sikora Date: Sat, 18 May 2013 13:49:06 +0200 Subject: Fixed #20429 -- Added QuerySet.update_or_create Thanks tunixman for the suggestion and Loic Bistuer for the review. --- tests/get_or_create/tests.py | 65 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'tests/get_or_create') diff --git a/tests/get_or_create/tests.py b/tests/get_or_create/tests.py index 847a6dec01..0f766ab128 100644 --- a/tests/get_or_create/tests.py +++ b/tests/get_or_create/tests.py @@ -131,3 +131,68 @@ class GetOrCreateThroughManyToMany(TestCase): Tag.objects.create(text='foo') a_thing = Thing.objects.create(name='a') self.assertRaises(IntegrityError, 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) + ) + p, created = Person.objects.update_or_create( + 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.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) + } + ) + self.assertTrue(created) + 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), + } + Person.objects.update_or_create(**params) + # If we execute the exact same statement, it won't create a Person. + p, created = Person.objects.update_or_create(**params) + self.assertFalse(created) + + def test_integrity(self): + # If you don't specify a value or default value for all required + # fields, you will get an error. + self.assertRaises(IntegrityError, + Person.objects.update_or_create, first_name="Tom", last_name="Smith") + + def test_mananual_primary_key_test(self): + # If you specify an existing primary key, but different other fields, + # then you will get an error and data will not be updated. + ManualPrimaryKeyTest.objects.create(id=1, data="Original") + self.assertRaises(IntegrityError, + ManualPrimaryKeyTest.objects.update_or_create, id=1, data="Different" + ) + self.assertEqual(ManualPrimaryKeyTest.objects.get(id=1).data, "Original") + + def test_error_contains_full_traceback(self): + # update_or_create should raise IntegrityErrors with the full traceback. + # This is tested by checking that a known method call is in the traceback. + # We cannot use assertRaises/assertRaises here because we need to inspect + # the actual traceback. Refs #16340. + try: + ManualPrimaryKeyTest.objects.update_or_create(id=1, data="Different") + except IntegrityError as e: + formatted_traceback = traceback.format_exc() + self.assertIn('obj.save', formatted_traceback) -- cgit v1.2.1