【问题标题】:Django - Scheduled eventDjango - 预定事件
【发布时间】:2020-05-11 17:12:37
【问题描述】:

当当前日期超过expiration_date 时,我希望更改此模型的status。我正在阅读有关 Celery 的后台任务和异步任务......我走对了吗?有没有更直接的方法来做到这一点?如果有人可以给我提示或遵循的东西,我将不胜感激。感谢收听。

class MyModel(models.Model):
    status          = models.BooleanField...
    expiration_date = models.DateField....
    [...]

【问题讨论】:

  • 我认为您在这里不需要计划任务。您可以根据expiration_date 字段计算该项目是否过期。
  • 我可以在没有 post 方法或其他强制方法的情况下自动进行此更改吗?

标签: django events schedule


【解决方案1】:

你不需要在模型中存储status,你可以简单地.annotate(..) [Django-doc]它,所以如果模型看起来像:

class MyModel(models.Model):
    expiration_date = models.DateField(db_index=True)

所以没有 status 字段。然后您可以使用以下方法进行注释:

from django.db.models import BooleanField, ExpressionWrapper, Q
from django.db.models.functions import Now

MyModel.objects.annotate(
    satus=ExpressionWrapper(
        Q(expiration_date__gt=Now()),
        output_field=BooleanField()
    )
)

如果expiration_date 在未来,则由此查询集产生的MyModel 对象将具有一个额外的属性.status,即True

如果你经常需要这个,你可以创建一个manager [Django-doc],它会在你每次访问MyModel.objects时自动注释项目:

from django.db.models import BooleanField, ExpressionWrapper, Q
from django.db.models.functions import Now

class MyModelManager(models.Manager):

    def get_queryset(self, *args, **kwargs):
        super().get_queryset(*args, **kwargs).annotate(
            satus=ExpressionWrapper(
                Q(expiration_date__gt=Now()),
                output_field=BooleanField()
            )
        )

class MyModel(models.Model):
    expiration_date = models.DateField(db_index=True)

    objects = MyModelManager()

这不需要计划任务,这很难管理:如果您稍后编辑expiration_date,那么您需要以某种方式“删除”已计划的任务并安排一个新的任务,这可能是“棘手的” .如果计划任务已经完成,则必须“撤消”它。

通过使用注释,您可以确保 status 仅基于 expiration_dateNow() 的值相比。

【讨论】:

    猜你喜欢
    • 2016-08-09
    • 2011-01-23
    • 2010-12-26
    • 2022-12-06
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    相关资源
    最近更新 更多