【发布时间】:2016-10-31 17:03:16
【问题描述】:
如何以原子方式比较-交换-保存 Django Model 实例 Field 的值? (使用 PostgreSQL 作为数据库后端)。
一个示例用例是确保具有相似内容的多个帖子(例如,提交相同表单)仅生效一次,而不依赖于不安全且仅有时有效的客户端 JavaScript 或表单 UUID 的服务器端跟踪,这对恶意的多发帖子是不安全的。
例如:
def compare_exchange_save(model_object, field_name, comp, exch):
# How to implement?
....
from django.views.generic.edit import FormView
from django.db import transaction
from my_app.models import LicenseCode
class LicenseCodeFormView(FormView):
def post(self, request, ...):
# Get object matching code entered in form
license_code = LicenseCode.objects.get(...)
# Safely redeem the code exactly once
# No change is made in case of error
try:
with transaction.atomic()
if compare_exchange_save(license_code, 'was_redeemed', False, True):
# Deposit a license for the user with a 3rd party service. Raises an exception if it fails.
...
else:
# License code already redeemed, don't deposit another license.
pass
except:
# Handle exception
...
【问题讨论】:
标签: python django postgresql atomic compare-and-swap