4π
That works, but I want to do this atomically [β¦]
Often, the answer is to use the QuerySet.update
method. That works when you want to do the same thing β or something that doesnβt need to change dynamically β to all the instances in a queryset.
Since the operation you want to perform appears to need a dynamic change to each instance in turn, you can instead use the select_for_update
method.
from django.db import transaction
dolors = LoremIpsum.objects.select_for_update().filter(dolor=True)
with transaction.atomic():
counter = 0
for lorem_ipsum in dolors:
lorem_ipsum.amet = counter
counter += 1
lorem_ipsum.save()
The documentation for select_for_update
says this does what you want:
All matched entries will be locked until the end of the transaction block, meaning that other transactions will be prevented from changing or acquiring locks on them.
Because the queryset causes the items to be βlocked until the end of the transaction blockβ, you need to perform your operations inside a transaction block using transaction.atomic
as above.