我正在研究Django博客,我需要能够安排帖子以便日后发布。 Celery非常适合初始安排帖子,但是当用户尝试更新帖子以使其重新安排或无限期取消时,我会遇到问题。
以下是我要做的事情:
def save(self, **kwargs):
'''
Saves an event. If the event is currently scheduled to publish,
sets a celery task to publish the event at the selected time.
If there is an existing scheduled task,cancel it and reschedule it
if necessary.
'''
import celery
this_task_id = 'publish-post-%s' % self.id
celery.task.control.revoke(task_id=this_task_id)
if self.status == self.STATUS_SCHEDULED:
from blog import tasks
tasks.publish_post.apply_async(args=[self.id], eta=self.date_published,
task_id=this_task_id)
else:
self.date_published = datetime.now()
super(Post, self).save(**kwargs)
问题是,一旦Celery任务ID被列为已撤销,即使在我尝试重新安排它之后它也会被撤销。这似乎是一个很常见的任务,应该有一个简单的解决方案。
答案 0 :(得分:2)
我不知道您的tasks.py文件是什么样的,但我认为它类似于以下内容:
from celery.decorators import task
@task
def publish_post(post_id):
''' Sets the status of a post to Published '''
from blog.models import Post
Post.objects.filter(pk=post_id).update(status=Post.STATUS_PUBLISHED)
您应该编辑任务中的过滤器,以确保当前状态为STATUS_SCHEDULED,并且date_published中的时间已过。 e.g:
from celery.decorators import task
@task
def publish_post(post_id):
''' Sets the status of a post to Published '''
from blog.models import Post
from datetime import datetime
Post.objects.filter(
pk=post_id,
date_published__lte=datetime.now(),
status=Post.STATUS_SCHEDULED
).update(status=Post.STATUS_PUBLISHED)
这样,用户可以来回更改状态,更改时间,如果任务在date_published列之后运行,则任务只会更改要发布的状态。无需跟踪ID或撤销任务。