3

私は 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 が取り消されたものとしてリストされると、再スケジュールを試みても取り消されたままになることです。これは、簡単な解決策があるはずの十分に一般的なタスクのようです。

4

1 に答える 1

3

あなたの 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 の時間が経過していることを確認する必要があります。例えば:

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 を追跡したり、タスクを取り消したりする必要はありません。

于 2010-12-22T16:11:23.033 に答える