Django - 添加游戏化功能

Sam*_* B. 5 django separation-of-concerns django-rest-framework

我有一个中等大小的 Django REST 应用程序,我希望为其添加游戏化功能。

该应用程序是一个学校网络应用程序,学生可以在其中创建模拟测验、参加教师发布的考试以及编写由其他学生和教师投票的教学内容。

我想添加一些游戏化功能,使应用程序更有趣,并激励参与和使用各种功能:例如,每个学生都会有一个个人“声誉”分数,并在完成某些操作后获得积分 - 学生可以以高分完成测验、提交某些内容或收到对此类内容的点赞时获得积分。

棘手的部分是,出于各种原因,我希望能够使此逻辑尽可能与现有代码库分离:关注点分离、根据需要插入/拔出引擎的能力、轻松停用某些组的功能的能力用户数量等

我在这里寻找的是一些特定于 Django 的软件工程建议。这是我正在考虑做的事情的高级描述——我想要一些关于该方法的建议。

  • 创建一个新gamification应用程序。在这里,我将拥有描述用户声誉变化以及可能的其他相关事件的模型。当游戏化相关事件发生时,应用程序还应该发送通知
  • gamification应用程序中公开一个基于回调的接口,其他主应用程序可以调用该接口来调度事件
  • 使用django-lifecycle包在触发器发生时调用回调gamification

这样,我现有的模型只会被触及以注册来自 django-lifecycle 的触发器(类似于信号)。例如,假设我想在学生交作业时给他们评分。假设我有一个AssignmentSubmission模型来处理作业提交。添加生命周期钩子后,它看起来像这样:

class AssignmentSubmission(models.Model):
    NOT_TURNED_IN = 0
    TURNED_IN = 1
    STATES = ((NOT_TURNED_IN, 'NOT_TURNED_IN'), (TURNED_IN, 'TURNED_IN'))

    user = models.ForeignKey(user)
    assignment = models.ForeignKey(assignment)
    state = models.PositiveSmallIntegerField(choices=STATES, default=NOT_TURNED_IN)

    @hook(AFTER_UPDATE, when="state", was=NOT_TURNED_IN, is_now=TURNED_IN)
     def on_turn_in(self):
        get_gamification_interface().on_assignment_turn_in(self.user)
Run Code Online (Sandbox Code Playgroud)

on_assignment_turn_in方法可能类似于:

def on_assignment_turn_in(user):
    ReputationIncrease.objects.create(user, points=50)
    notifications.notify(user, "You gained 50 points")
Run Code Online (Sandbox Code Playgroud)

这几乎只是一个提供想法的草图。

我不确定如何get_gamification_interface()运作。它应该返回一个单例吗?也许实例化一个对象?或者返回一个带有静态方法的类?我认为最好有一个像这样的 getter,而不是从gamification应用程序手动导入方法,但也许它也会产生太多的开销。

有什么好方法可以向项目添加“可插入”功能,这些功能本质上与现有模型和业务逻辑纠缠在一起,同时又尽可能少地接触这些功能?

小智 1

你的主意很好。在游戏化应用程序中添加您的视图,使用 LoginRequiredMixin 保护它,并通过检查AssignmentSubmission表中的相关记录是否存在并打开来扩展它。

通过这种方式,你就拥有了 100% 分离的游戏化视图、模型、逻辑等等……

在现有视图中,您可以添加指向游戏化视图的链接。