Заставьте django просмотреть временный «синглтон» в django rest - PullRequest
0 голосов
/ 29 апреля 2019

Честно говоря, я не знал, как озаглавить этот вопрос.Предположим, что такое мнение ниже.У моих пользователей может быть максимум 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, например, чтобы прояснить ситуацию.

1 Ответ

1 голос
/ 29 апреля 2019

Just

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() - здесь приведено руководство, в частности, об этом случае , которое будет выполнять атомное обновление в базе данных:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...