Django:如何在同一对象中提到的时间自动更改字段的值?

col*_*der 14 python django django-models celery django-celery

我正在为赛车活动开发一个django项目,其中数据库中的表有三个字段.

1)布尔字段,用于了解种族是否有效

2)比赛开始时间

3)比赛结束时间

在创建对象时,会指定start_time和end_time.如何在比赛开始时将布尔字段的值更改为True,并
在结束时将其更改为False?如何安排这些活动?

Rah*_*pta 17

要在特定时间后自动更新模型字段,可以使用Celery任务.

第1步:创建芹菜任务

我们将首先创建一个名为芹菜任务set_race_as_inactive,将设定is_active的标志race_objectFalse后,当前的日期比更大end_timerace_object.

Celery仅当当前时间大于竞赛对象时才执行此任务end_time.

@app.task
def set_race_as_inactive(race_object):
    """
    This celery task sets the 'is_active' flag of the race object 
    to False in the database after the race end time has elapsed.
    """

    race_object.is_active = False # set the race as not active 
    race_object.save() # save the race object 
Run Code Online (Sandbox Code Playgroud)

步骤2:使用eta参数调用此celery任务

创建芹菜任务后set_race_as_inactive,我们需要调用这个芹菜任务.

每当我们将新race_object数据保存到数据库中时,我们都会调用此任务.所以,每当一个新的race_object将被保存,芹菜任务将被解雇这只会之后执行end_timerace_object.

我们将使用调用任务apply_async()并将eta参数传递end_timerace_object.

根据Celery文档,

ETA(预计到达时间)允许您设置特定日期和时间,这是您执行任务的最早时间.

保证在指定的日期和时间之后的某个时间执行任务,但不一定在该确切的时间执行.

from my_app.tasks import set_race_as_inactive

class RaceModel(models.Model):

    ...

    def save(self, *args, **kwargs):
        ..
        create_task = False # variable to know if celery task is to be created
        if self.pk is None: # Check if instance has 'pk' attribute set 
            # Celery Task is to created in case of 'INSERT'
            create_task = True # set the variable 

        super(RaceModel, self).save(*args, **kwargs) # Call the Django's "real" save() method.

        if create_task: # check if task is to be created
            # pass the current instance as 'args' and call the task with 'eta' argument 
            # to execute after the race `end_time`
            set_race_as_inactive.apply_async(args=[self], eta=self.end_time) # task will be executed after 'race_end_time'
Run Code Online (Sandbox Code Playgroud)

这种检查self.pkNone这样只有在新创建的对象的情况下,将创建一个芹菜的任务就完成了.如果我们不这样做,那么对于每次.save()调用(INSERT或者UPDATE),都会创建一个我们不想要的芹菜任务.这将导致许多不必要的芹菜任务等待执行,并将超载我们的芹菜队列.

使用Celery 的好处是,is_active标志的更新将在后台异步自动发生,而无需担心手动更新它们.每次创建一个新的种族对象时,都会触发一个任务,Celery会将其执行推迟到end_time竞赛期间.经过之后end_time,Celery将执行该任务.