我有一个管理操作,如下所示:

def process(modeladmin, request, queryset):
    for reservation in queryset:
        if not reservation.processed:
            reservation.processed = True
            reservation.save()
            item = reservation.item
            item.available = F('available') - reservation.quantity
            item.save()

因此,管理员可以处理reservationitem。每当他这样做时,reservation就被标记为已处理,可用的items的数量将按reservation中指定的数量减少。
对于所有管理操作,管理员可以一次处理多个reservations。如果reservations有不同的items,一切都会顺利。但如果两个reservations共享一个item,则可用items的数量只会按上次处理的reservation中指定的数量减少。
我认为F()表达式只是针对这种情况:我想对item进行许多更改,并使它们增加或减少item上的一个属性,而不必遇到竞争条件。我错过了什么?

最佳答案

这并不是真正使用F对象的方法。一旦你分离了提取和保存的步骤,你本质上就是让它显式地非原子化。
您应该使用update来实现这一点,因此项目部分应该是:

Item.objects.filter(id=reservation.item.id).update(available=F('available')-reservation.quantity)

或者类似的东西。

10-06 15:03