我的管理操作如下:
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()
因此,管理员可以处理reservation
的{{1}}。无论何时,item
都会被标记为已处理,可用reservation
的数量会减少items
中指定的数量。
对于所有管理操作,管理员可以一次处理多个reservation
。如果reservations
具有所有不同的reservations
,那么一切顺利。但如果两个items
共享一个reservations
,则可用item
的数量仅会减少上一个items
处理中指定的数量。
我认为reservation
表达式只适用于这种情况:我希望对F()
进行许多更改,并让它们在item
上增加或减少属性,而不会遇到竞争条件。我错过了什么?
答案 0 :(得分:1)
这并不是你如何使用F对象。一旦你将保存的步骤分开,你实际上将其明确地视为非原子。
您应该使用update
,因此项部分应为:
Item.objects.filter(id=reservation.item.id).update(available=F('available')-reservation.quantity)
或类似的东西。
答案 1 :(得分:-2)
F()表达式用于查询,例如,当您想在SQL中执行此操作时:
SELECT * FROM foo WHERE foo_col = bar_col
你会这样做:
Foo.objects.filter(foo_col=F('bar_col'))
无论如何,您要求的项目只能根据上次预订而减少,这意味着您必须对循环预订的方式有所启发。一个选项是按项目ID排序查询集,每次ID“更改”时,根据该项目的上次预订调整可用金额。