Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django-如何根据实际日期自动更新对象属性?_Python_Django - Fatal编程技术网

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

Python Django-如何根据实际日期自动更新对象属性?,python,django,Python,Django,我需要一个对象属性自动更新过去的一些实际日期和时间。我在该类中有一个类和一个方法来尝试执行此操作,但这里的问题是我需要调用该方法(或访问@property)以应用此方法。 代码如下所示: class Foo(models.Model): status = models.CharField() expiring_time = models.DateTimeField() def is_active(self): date = datetime.datet

我需要一个对象属性自动更新过去的一些实际日期和时间。我在该类中有一个类和一个方法来尝试执行此操作,但这里的问题是我需要调用该方法(或访问@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()
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)
我发现了一些类似的问题,但似乎没有一个能达到我想要的目的。我听说芹菜可以执行预定的任务,但据我所知,这只是继续调用该方法,而不是我正在寻找的方法


我想知道是否有办法保持此方法“始终处于活动状态”,或者有什么办法可以实现此目的?

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

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()
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迭代期间。这可能会导致性能问题

请看一下文档:

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