У меня есть поле «прогресс» на уровне
class Level(models.Model):
level = models.CharField(max_length=50, unique=True)
helper = models.TextField(null=True, blank=True)
progress = models.IntegerField(default=0)
Мне нужно добавить 1 к «прогрессу». Все, что мне нужно, это хранить другое значение для каждого пользователя. Я действительно не могу понять, как это уладить. Теперь у меня есть класс LevelProgress в views.py, который добавляет 1 к области прогресса, но он добавляет 1 глобально.
class LevelProgress(APIView):
def get(self, request, id):
queryset_ = Level.objects.get(pk=id)
queryset_.progress += 1
queryset_.save()
serializer = LevelFullSerializer(queryset_)
return Response(serializer.data)
Как добавить 1 для текущего пользователя?
Всего 2 ответа
Ну, моделирование неверно. Вы не можете сохранить прогресс на этом объекте Level
, вам нужно добавить дополнительную модель, например UserLevel
с ForeignKey
s для User
и Level
, и UserLevel
ForeignKey
:
from django.conf import settings
class Level(models.Model):
level = models.CharField(max_length=50, unique=True)
helper = models.TextField(null=True, blank=True)
class UserLevel(models.Model):
level = models.ForeignKey(Level, on_delete=models.CASCADE)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
progress = models.IntegerField(default=0)
Итак, теперь мы создаем для User
определенный объект UserLevel
, и мы можем обновить этот прогресс. Мы можем даже сделать это с помощью одной функции update_or_create(..)
:
class LevelProgress(APIView):
def get(self, request, id):
ul, created = UserLevel.objects.get_or_create(
level_id=id,
user_id=request.user.pk
defaults={'progress': 1}
)
if not created:
ul.progress += 1
ul.save()
serializer = LevelFullSerializer(ul.level)
return Response(serializer.data)
Вы также можете изменить LevelFullSerializer
для сериализации прогресса этого пользователя.
При этом запрос GET с «побочными эффектами» на самом деле не разрешен в соответствии с рекомендациями HTTP. Обычно один из них меняет объекты в базе данных с запросами POST, PUT, PATCH и т. Д.
Вы можете добавить поле OneToOneField
к модели Level
следующим образом:
from django.conf import settings
class Level(models.Model):
level = models.CharField(max_length=50, unique=True)
helper = models.TextField(null=True, blank=True)
progress = models.IntegerField(default=0)
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
Теперь, на ваш взгляд, вы можете получить уровень для текущего пользователя:
class LevelProgress(APIView):
def get(self, request, id):
queryset_ = Level.objects.get(user=request.user)
queryset_.progress += 1
queryset_.save()
serializer = LevelFullSerializer(queryset_)
return Response(serializer.data)