Как я могу с помощью атомарного сравнения-обменять значение Django Model
экземпляр Field
? (Использование PostgreSQL в качестве базы данных БД).Атомно-сравнить поле модели в Django
Примером использования является то, что несколько сообщений с похожим контентом (например, отправления одной и той же формы) вступают в силу только один раз, не полагаясь на небезопасное и только иногда работающее на стороне клиента javascript или серверное отслеживание формы UUIDs , который не защищен от вредоносных множественных сообщений.
Например:
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
...
Гарантируется ли это, что это атомный? Я не вижу этого в документах. Если это не так, то в моем случае использования для двух разных запросов можно ввести раздел «Депозит лицензии» – Danra
Это единый вызов базы данных. Это настолько же атомно, насколько это возможно. –
@ DanielRoseman, который является атомарным или нет? То есть, предполагая бэкэнд PostgreSQL, возможно ли для двух одновременных запросов одновременно вызвать этот метод, чтобы оба успешно обновили значение? Или это гарантирует, что в лучшем случае это будет успешным? – Danra