У меня есть проект Django 1.7 beta 1 со стандартной формой регистрации пользователя.
Концептуально имеет смысл, если проверка формы завершится ошибкой, если имя пользователя уже занято. Однако проверка формы и сохранение успешно созданной пользовательской модели — это отдельные шаги, поэтому существует состояние гонки, при котором проверка может пройти, но фактическая user.save()
может завершиться ошибкой с IntegrityError
.
Я не понимаю, что произойдет, если и проверка формы, и шаг user.save()
будут заключены в один и тот же блок transaction.atomic()
— я предполагаю, что postgres не будет создавать никаких блокировок при чтении таблицы, чтобы проверить, существует ли строка, и, следовательно, транзакция вообще не предотвратит состояние гонки.
Предполагая, что это так, как лучше всего справиться с этим? Вот варианты, которые я пока рассматриваю:
- Полностью пропустите проверку уникальности имени пользователя и просто ловите
IntegrityError
во время сохранения, добавляя в список ошибок формы вручную. Это пуленепробиваемое, но перемещает некоторую логику проверки за пределы определения формы. - Выполните как этап проверки, так и блок try/except вокруг
IntegrityError
. Это может привести к дублированию кода, но теперь форма работает изолированно, и использование формы в представлении не вызывает состояния гонки.