老实说,我不知道如何给这个问题加上标题。假设下面这样一个视图。我的用户口袋里最多可以放10美元。我添加了一个点击该视图的按钮,并一次添加了1美元,直到达到10美元。这只是一个例子。
def my_view(request):
money_to_add = 10 - request.user.money
for i in range(0, money_to_add):
user.money += 1
request.user.save()
return HttpResponse(“Ok!”)
问题是,如果用户两次快速单击按钮,则会向帐户添加两次“ 10-request.user.money”。
仅修改视图,如何解决此问题? 我宁愿避免使用外部软件包或修改模型的行为。
谢谢。
编辑:使用基于类的视图是可以的!我只是以fbv为例进行了说明。
答案 0 :(得分:1)
只是
user.money = min(10, user.money + 1)
始终会将user.money
的最大值限制为10。
但是,这不会考虑并发性。当发生这种情况时,您可能会陷入竞争状态:
REQUEST 1 REQUEST 2
load user (money=7)
user.money += 1 load user (money=7)
user.save() (money=8) user.money += 1
user.save() (money=8) <-- should be 9
为此,您必须使用F()
– the guide here talks about this case in particular,它将自动在数据库中进行更新:
user.money = Min(10, F('money') + 1)
user.refresh_from_db() # if you need `user.money` to be the concrete value; otherwise it's an expression still