Создание динамической системы оценки квестов и значков на Django
Модели
Квест
class Quest(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
criteria = models.JSONField() # Store criteria as JSON
reward_points = models.IntegerField(default=0)
def __str__(self):
return self.name
Значок
class Badge(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
criteria = models.JSONField() # Store criteria as JSON
reward_points = models.IntegerField(default=0)
def __str__(self):
return self.name
UserQuestProgress
class UserQuestProgress(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
quest = models.ForeignKey(Quest, on_delete=models.CASCADE)
current_value = models.IntegerField(default=0)
target_value = models.IntegerField()
completed = models.BooleanField(default=False)
completed_at = models.DateTimeField(null=True, blank=True)
def save(self, *args, **kwargs):
if self.current_value >= self.target_value:
self.completed = True
if not self.completed_at:
self.completed_at = timezone.now()
super().save(*args, **kwargs)
UserBadgeProgress
class UserBadgeProgress(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
badge = models.ForeignKey(Badge, on_delete=models.CASCADE)
current_value = models.IntegerField(default=0)
target_value = models.IntegerField()
completed = models.BooleanField(default=False)
completed_at = models.DateTimeField(null=True, blank=True)
def save(self, *args, **kwargs):
if self.current_value >= self.target_value:
self.completed = True
if not self.completed_at:
self.completed_at = timezone.now()
super().save(*args, **kwargs)
Я работаю над платформой для социальных сетей, где пользователи могут зарабатывать награды (квесты и значки) на основе своих действий. Моя цель - создать гибкую систему, которая могла бы оценивать эти награды динамически, без необходимости жестко задавать новые условия каждый раз, когда мы вводим новый квест или значок.
Что мы сделали до сих пор:
- Модели для квестов и значков: Мы определили модели для
Quest
,Badge
,UserQuestProgress
иUserBadgeProgress
, которые отслеживают прогресс пользователя. - Критерии JSON: Мы используем JSON для определения критериев для каждого квеста или бейджа. Например:
{ "Post": { "reaction_type_within_timeframe": ["dislike", 30, 50] } }
- Функция оценки: У нас есть функция
evaluate_quest
, которая обрабатывает JSON критериев для вычисления прогресса пользователя:def evaluate_quest(user, criteria): # Evaluate criteria and calculate progress
- Задача Целери: Когда пользователь переходит на страницу квеста или бейджа, запускается задача Celery для оценки его прогресса и обновления
UserQuestProgress
илиUserBadgeProgress
.
Текущие задачи:
- Жесткое кодирование сценариев: Текущая реализация по-прежнему требует от нас жесткого кодирования новых сценариев в функции
evaluate_quest
. Мы стремимся динамически обрабатывать различные сложные условия, но испытываем трудности с неизвестными будущими сценариями. - Примерные сценарии:
- Впервые разместите обновление статуса или любое другое сообщение:
{ "Post": { "first_post": true } }
- Вы заполнили все поля информации о своем профиле:
{ "Profile": { "complete_profile": true } }
- Выставите 50 лайков и/или любовных реакций на сообщения ваших подписчиков:
{ "Reaction": { "reaction_type": ["like", "love"], "count": 50, "on_followers_posts": true } }
- Получили 100+ лайков и 50+ комментариев к одному посту:
{ "Post": { "likes": 100, "comments": 50, "single_post": true } }
- Пользователь первым отреагировал на 50+ постов друзей:
{ "Reaction": { "first_reaction": true, "on_friends_posts": true, "count": 50 } }
- Впервые разместите обновление статуса или любое другое сообщение:
Рабочий процесс:
- Когда пользователь переходит на страницу квеста или бейджа, запускается задача Celery.
- Задача использует
get_or_create(user, quest|badge)
для обеспечения экземпляра прогресса. - Вызывается функция
evaluate_quest
для вычисления текущих и целевых значений. - Модели
UserQuestProgress
иUserBadgeProgress
имеют переопределенные методыsave
для отметки завершения, если текущее значение соответствует или превышает целевое значение. - После сохранения сигнал
post_save
уведомляет пользователя через WebSocket о завершении квеста или бейджа.
Текущая evaluate_quest
функция:
Опасения:
- Текущая реализация по-прежнему требует от нас жесткого кодирования определенных условий в функции
evaluate_quest
. - Мы хотим более динамичный подход, который может обрабатывать неизвестные будущие сценарии, не требуя изменений в коде.
Просьба о помощи:
- Как сделать функцию
evaluate_quest
более динамичной для обработки различных сложных условий без жесткого кодирования каждого нового сценария? - Есть ли в Django какие-либо существующие библиотеки или паттерны, которые могут помочь достичь такой гибкости?
- Примеры сложных условий, которые нам необходимо обработать:
- Размещение обновления статуса в первый раз.
- Заполнение всех полей информации профиля.
- Поставить 50 лайков и/или любовных реакций на сообщения подписчиков.
- Получение 100+ лайков и 50+
комментарии к одному сообщению.
- Реагируя первым на сообщения 50+ друзей.
Текущий рабочий процесс:
- Пользователь переходит на страницу квеста или бейджа, вызывая задачу Celery.
- Задача оценивает все квесты или бейджи для пользователя с помощью
get_or_create(user, quest|badge)
. - Вызывается функция
evaluate_quest
для вычисления прогресса. - Прогресс обновляется на основе ответа от функции
evaluate_quest
. - Метод
save
вUserQuestProgress
иUserBadgeProgress
автоматически отмечает завершение, если текущее значение соответствует или превышает целевое значение. - Сигнал
post_save
уведомляет пользователя через WebSocket о завершении квеста или бейджа.
Любые соображения или предложения, чтобы сделать эту систему более надежной и динамичной, будут высоко оценены. Спасибо!