首页 > 解决方案 > 使用后台线程定期刷新字段的值

问题描述

首先,标题不是 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() 以便我可以检查它是否确实被调用。当我运行服务器时,我收到“预定”消息,但它似乎实际上并没有再次调用该函数。

标签: pythondjangodjango-models

解决方案


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

该文档提到了安排 Django 管理命令的可能性。所以这实际上可能是另一种可能性:您编写一个管理命令来更新您的字段,然后使用一次性系统命令设置 cron 作业,或者在 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)


推荐阅读