How to exchange the key field in a transaction?

class Test(models.Model):
id = models.AutoField(primary_key=True)
name = models.TextField(null=False,blank=False, unique=True)
class Meta:
db_table = ‘test’

Add two records to this table:
r1 = Test()
r1.name = ‘Tom’
r1.save()

r2 = Test()
r2.name = ‘Sam’
r2. save()

Now I want to exchange the names in these two record in a transaction, how?

r1 = Test.objects.filter(id=1).first()
r1.name = ‘Sam’

r2 = Test.objects.filter(id=2).first()
r2.name = ‘Tom’

with transaction.atomic():
Test.objects.bulk_update([r1, r2], fields=[‘name’])

Previous code will raise an IntegrityError: ‘Sam’ is exists.
How can I save these two record in a transaction?

Use the old “three-step” exchange technique

  • Change r1.name to some random unique value
  • Change r2.name to the original r1.name value
  • Change r1.name to the original r2.name value

It’s three db updates instead of two, but it does keep the constraints satisfied.

Hi, KenWhitesell:
Thank you for all your assistance. I use this method now.