4

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

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一个item. 每当他这样做时,都会将reservation其标记为已处理,并且可用items数量会减少 中指定的数量reservation

正如所有管理员操作都会发生的那样,管理员可以reservations一次处理多个操作。reservations如果一切都不同,一切都会顺利items。但是如果两个reservations共享一个item,可用的数量items只会减少最后reservation处理中指定的数量。

我认为F()表达式仅适用于这种情况:我想进行许多更改item并让它们增加或减少属性,item而不会遇到竞争条件。我错过了什么?

4

2 回答 2

0

这并不是你真正使用 F 对象的方式。一旦你将获取和保存的步骤分开,你本质上就是让它明确地成为非原子的。

你应该使用update它,所以item部分应该是:

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

或类似的东西。

于 2014-03-19T14:16:47.263 回答
-2

F() 表达式用于查询中,例如,当您想在 SQL 中执行此操作时:

SELECT * FROM foo WHERE foo_col = bar_col

你会这样做:

Foo.objects.filter(foo_col=F('bar_col'))

无论如何,您要求仅根据最后一次预订减少项目意味着您必须对如何循环预订有一点创意。一种选择是按项目 id 对查询集进行排序,并且每次 id “更改”时,根据该项目的最后预订调整可用数量。

于 2012-05-24T04:05:24.397 回答