Django如何根据实际日期自动更新对象属性?

2024-05-16 21:08:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要一个对象属性自动更新过去的一些实际日期和时间。我在该类中有一个类和一个方法来尝试执行此操作,但这里的问题是我需要调用该方法(或访问@property)以应用此方法。
代码如下所示:

class Foo(models.Model):
    status =  models.CharField()
    expiring_time = models.DateTimeField()

    def is_active(self):
        date = datetime.datetime.now()
        if date > self.expiring_time:
            self.status = "expired"
        self.save()

我发现了一些类似的问题,但似乎没有一个能达到我想要的目的。我听说芹菜可以执行预定的任务,但据我所知,这只是继续调用该方法,而不是我正在寻找的方法

我想知道是否有办法保持这种方法“始终有效”,或者有什么办法可以做到这一点


Tags: 对象方法代码selfdatetimedate属性time
2条回答

保持一种方法“始终处于活动状态”似乎并不实际。或者其他一些工具,比如cronjob或芹菜,需要继续调用它,或者只是不将值存储在数据库中。您可以使用annotate,使用^{}向queryset内的对象添加状态值,如下所示:

from django.db.models import Case, CharField, Value, When
foo = Foo.objects.annotate(
    is_active = Case(
        When(
            date__lte=datetime.now(), then=Value("expired")
        ),
        default=Value("not expired"),
        output_field=CharField()
    )
)

for val in foo:
   print(val.is_active)

您可以在模型中使用post_init信号

此信号在实例初始化后立即发送

from django.db.models.signals import post_init
from django.dispatch import receiver

class Foo(models.Model):
    status =  models.CharField()
    expiring_time = models.DateTimeField()

@receiver(post_save, sender=User)
def is_active(sender, instance, **kwargs):
    date = datetime.datetime.now()
    if date > instance.expiring_time:
        instance.status = "expired"
    instance.save()

注意:每次返回实例时,此信号将执行此函数;甚至在queryset迭代期间。这可能会导致性能问题

看看文档:https://docs.djangoproject.com/en/3.0/ref/signals/#post-init

另一种方法是每次实例化Foo模型时调用此函数。它将使您的业务逻辑超出您的模型

相关问题 更多 >