我有一个带有标准用户注册表单的 Django 1.7 beta 1 项目。
从概念上讲,如果用户名已经被占用,表单验证失败是有意义的。但是,表单验证和成功创建的用户模型的保存是单独的步骤,因此存在一个竞争条件,即验证可以通过,但实际user.save()
可能会失败并显示IntegrityError
.
我不清楚如果表单验证和user.save()
步骤都包装在同一个transaction.atomic()
块中会发生什么——我的假设是 postgres 在读取表以检查行是否存在时不会创建任何锁,因此事务将根本不阻止比赛条件。
假设是这种情况,处理这个问题的最佳方法是什么?以下是我目前正在考虑的选项:
- 完全跳过用户名唯一性验证,只需抓住
IntegrityError
保存时间,手动添加到表单错误列表中。这是防弹的,但是将一些验证逻辑移到了表单定义之外。 - 执行验证步骤和
IntegrityError
. 这可能会添加重复的代码,但现在表单是独立工作的,并且在视图中使用表单不会导致竞争条件。