使用后台线程定期刷新字段的值

时间:2019-07-19 15:48:26

标签: python django django-models

首先,标题不是100%准确的,因为我不太在乎解决方案是否要使用线程。

在我的django项目中,我有一个带有某些字段的模型。字段之一由函数计算。所以在我的 models.py 中,它看起来像这样:

class Feed(models.Model):

    name = models.ForeignKey(Name, on_delete=models.CASCADE, default=0)
    source = models.ForeignKey(Source, on_delete=models.CASCADE, default=0)

    def set_status(self, _status=None):
        # code that i have to implement
        if status is None:
            return 'ACTIVE'
        else:
            return _status
    status = property(set_status)

我想做的是能够定期重新设置状态字段的值,然后刷新页面以使用户具有更新的状态。 我的主要想法是以某种方式调用它将等待套接字消息的后台线程,例如:

def wait_for_status_change(self):
    #setting the socket
    while True:
        # socket wait to receive and edit the message accordingly
        self.set_status(socket_message)

很明显,我必须指定要更改状态字段的模型的哪个特定对象。 我尝试使用Celery,但是我认为原因太复杂了,因此我不想将其用于该问题。

我也想到了使用调度程序的解决方案,但是我真的不了解在这种情况下如何使用它。

我知道有些事情我被误解了,也许我没有以正确的方式思考它,所以我将向任何方向的任何建议表示感谢。

编辑: 我尝试使用Django-q调度程序,但无法正常工作。 在文档中提到:

  

您可以通过管理页面或直接从您的代码中管理它们。

所以我将此代码添加到了 admin.py 中:

    if schedule('Feed.set_status', 'not active', schedule_type='I', minutes=1, repeats=-1, next_run=datetime.now()):
        print('SCHEDULED')

并在我的函数中添加了一些print(),以便我可以检查它是否确实被调用。 当我运行服务器时,我收到“预定的”消息,但似乎并没有真正在再次调用该函数。

1 个答案:

答案 0 :(得分:0)

Celery对于这项任务确实很重要,但是无论如何我还是会去图书馆。我会尝试使用django-q。它具有schedulers,并且可以在没有外部依赖项的情况下使用它(使用Django ORM作为消息代理,而不是像Redis这样的其他工具)。它还有其他优点,例如,我们可以在Django管理员中查看任务。

该文档提到了安排Django管理命令的可能性。因此,这实际上可能是另一种可能性:您编写一个管理命令来更新您的字段,并使用一次性系统命令或使用cron library在python中设置cron作业(那里没有偏好)为我)。

django-q调度程序易于设置,看起来像这样:

from django_q.models import Schedule

Schedule.objects.create(func='math.copysign',
                        hook='hooks.print_result',
                        args='2,-2',
                        schedule_type=Schedule.DAILY
                        )

我们可以更精确地安排时间:next_run=arrow.utcnow().replace(hour=18, minute=0)

其他轻量级任务队列包括Huey(需要redis)和others