from django.db import DatabaseError, IntegrityError, transaction from django.test import TestCase from .models import ( Counter, InheritedCounter, ProxyCounter, SubCounter, SubSubCounter, WithCustomPK, ) class ForceTests(TestCase): def test_force_update(self): c = Counter.objects.create(name="one", value=1) # The normal case c.value = 2 c.save() # Same thing, via an update c.value = 3 c.save(force_update=True) # Won't work because force_update and force_insert are mutually # exclusive c.value = 4 msg = "Cannot force both insert and updating in model saving." with self.assertRaisesMessage(ValueError, msg): c.save(force_insert=True, force_update=True) # Try to update something that doesn't have a primary key in the first # place. c1 = Counter(name="two", value=2) msg = "Cannot force an update in save() with no primary key." with self.assertRaisesMessage(ValueError, msg): with transaction.atomic(): c1.save(force_update=True) c1.save(force_insert=True) # Won't work because we can't insert a pk of the same value. c.value = 5 with self.assertRaises(IntegrityError): with transaction.atomic(): c.save(force_insert=True) # Trying to update should still fail, even with manual primary keys, if # the data isn't in the database already. obj = WithCustomPK(name=1, value=1) msg = "Forced update did not affect any rows." with self.assertRaisesMessage(DatabaseError, msg): with transaction.atomic(): obj.save(force_update=True) class InheritanceTests(TestCase): def test_force_update_on_inherited_model(self): a = InheritedCounter(name="count", value=1, tag="spam") a.save() a.save(force_update=True) def test_force_update_on_proxy_model(self): a = ProxyCounter(name="count", value=1) a.save() a.save(force_update=True) def test_force_update_on_inherited_model_without_fields(self): """ Issue 13864: force_update fails on subclassed models, if they don't specify custom fields. """ a = SubCounter(name="count", value=1) a.save() a.value = 2 a.save(force_update=True) class ForceInsertInheritanceTests(TestCase): def test_force_insert_false(self): with self.assertNumQueries(3): obj = SubCounter.objects.create(pk=1, value=0) with self.assertNumQueries(2): SubCounter(pk=obj.pk, value=1).save() obj.refresh_from_db() self.assertEqual(obj.value, 1) with self.assertNumQueries(2): SubCounter(pk=obj.pk, value=2).save(force_insert=False) obj.refresh_from_db() self.assertEqual(obj.value, 2) def test_force_insert_false_with_existing_parent(self): parent = Counter.objects.create(pk=1, value=1) with self.assertNumQueries(2): SubCounter.objects.create(pk=parent.pk, value=2) def test_force_insert_parent(self): with self.assertNumQueries(3): SubCounter(pk=1, value=1).save(force_insert=True) def test_force_insert_with_grandparent(self): with self.assertNumQueries(4): SubSubCounter(pk=1, value=1).save(force_insert=True) def test_force_insert_with_existing_grandparent(self): # Force insert only the last child. grandparent = Counter.objects.create(pk=1, value=1) with self.assertNumQueries(4): SubSubCounter(pk=grandparent.pk, value=1).save(force_insert=True)