首页 > 解决方案 > Django - 预定事件

问题描述

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

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

标签: djangoeventsschedule

解决方案


您不需要将 存储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()
    )
)

MyModel从此查询集中产生的对象将具有一个额外的属性.status,即True是否expiration_date在将来。

如果您经常需要这个,您可以创建一个管理器[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_date比较的值Now()


推荐阅读