Как "создать или обновить" с помощью объекта F?

Мне нужно создать LeaderboardEntry, если он не существует. Он должен быть обновлен новым значением (текущее + новое), если он существует. Я хочу добиться этого с помощью одного запроса. Как я могу это сделать?

Текущий код выглядит следующим образом: (2 запроса)

reward_amount = 50

LeaderboardEntry.objects.get_or_create(player=player)
LeaderboardEntry.objects.filter(player=player).update(golds=F('golds') + reward_amount)

PS: Значение по умолчанию "золотых" равно 0.

Я думаю, что ваша проблема заключается в методе get_or_create(), который возвращает кортеж с двумя значениями, (object, created) поэтому вы должны получить их в вашем коде следующим образом:

reward_amount = 50

entry, __ = LeaderboardEntry.objects.get_or_create(player=player)
entry.golds += reward_amount
entry.save()

Это будет работать лучше, чем ваш фактический код, просто позволит избежать двух запросов.

Конечно, метод save() снова ударит по вашей базе данных.

у вас может быть на один запрос меньше с помощью defaults :

reward_amount = 50

leader_board, created = LeaderboardEntry.objects.get_or_create(
    player=player,
    defaults={
        "golds": reward_amount,
    }
)

if not created:
    leader_board.golds += reward_amount
    leader_board.save(update_fields=["golds"])

Вы можете решить это с помощью update_or_create:

LeaderboardEntry.objects.update_or_create(
    player=player,
    defaults={
        'golds': F('golds') + reward_amount
    }
)

EDIT:

Извините, F выражения в update_or_create пока не поддерживаются.

Вернуться на верх