Django / postgres - ведение таблицы счетчиков
Я хочу вести текущий счетчик для каждого пользователя, который будет передаваться в элементы пользователя.
<<<ТаблицаUser
будет иметь колонку item_counter
class Item:
name = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE)
item_num = models.IntegerField() # should be populated from the user table
Вопрос, когда пользователь создает элемент, какой лучший способ увеличить счетчик и скопировать новый счетчик в новый созданный элемент, атомарно?
Технически я атомарно должен:
- Ввести и получить счетчик пользователя
- Создайте новый элемент со значением для
item_counter
Каким образом это можно сделать с помощью django / postgres?
EDIT - пример:
Таблица пользователей:
| username | item_counter |
| john | 20 |
Теперь пользователь посылает POST /item
. Результатом будет:
Таблица элементов:
| name | item_num |
| my_item | 21 |
Таблица пользователей:
| username | item_counter |
| john | 21 |
Конечно, пользователей может быть много. У каждого пользователя есть свой item_counter
.
Насколько я понимаю, вам нужно присвоить специальное целое число только что созданной записи элемента, значение которого будет получено из переменной счетчика пользователя. Переменная счетчика пользователя будет увеличиваться каждый раз, когда пользователь создает новую запись элемента.
В соответствии с вашей задачей вот ваше решение.
В вашем class Item
объявите метод для увеличения значения счетчиков
from django.db import transaction, IntegrityError #Django inbuilt atomicity transaction block
class Item(models.Model):
name = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE)
item_num = models.IntegerField()
def increment_counter(self):
temp = self #Here I have used temp so that it does not throw an out of reference error in your atomic block below
with transaction.atomic():
# This code executes inside a transaction.
temp.user.counter = temp.user.counter + 1
temp.user.save()
temp.item_num = temp.user.counter
temp.save()
В вашем методе views.py
POST после сохранения/создания нового элемента необходимо вызвать метод item.increment_counter()
newly_created_item = Item.objects.create(....some data)
try:
newly_created_item.increment_counter()
except IntegrityError:
# Handle any exception here