django:在后台更新模型

Luv*_*eet 0 python django django-models

我有一个叫预订的模型。它具有start_timeend_time字段。它也有一个is_active领域。

现在,假设预订有start_time = 2017/Nov/22 12:00:00end_time = 2017/Nov/22 14:00:00

现在,当服务器崩溃时,

1-如果当前时间在开始时间和结束时间之间,则is_active应该为True。

2-当前时间大于end_time或小于预订的start_time,我要设置is_active = False。

我希望它在后台连续运行,以便它必须在数据库中实时保持预订is_active状态。如何在django中做到这一点?

Rob*_*ley 6

根据您的需求,您可能会比使用另一个库或设置任何后台任务更简单。

例如,您可以在视图中生成这样的活动预订列表,而不是在后台运行作业:

from django.utils import timezone

now = timezone.now()
active_bookings = Booking.objects.filter(
    start_time__gte=now,
    end_time__lt=now
)
Run Code Online (Sandbox Code Playgroud)

如果您希望能够确定单个预订是否处于活动状态,则可以将该模型作为属性

# myapp/models.py
class Booking(models.Model):

    @property
    def is_active(self):
        now = timezone.now()
        return self.start_time >= now and self.end_time < now

# In your view or in a utility function
myBooking = Booking.objects.get(id=12345)
print(myBooking.is_active)
Run Code Online (Sandbox Code Playgroud)

如果您绝对需要异步执行它(也许与此相关的计算量很大的数据操作),则可以创建一个管理命令来更新所有对象

# myapp/management/commands/update_active_bookings.py

from django.core.management.base import BaseCommand

class Command(BaseCommand):

    def handle(self, *args, **kwargs):
        now = timezone.now()
        for booking in Booking.objects.all().iterator():
          is_active = self.start_time <= now and self.end_time > now
          if self.is_active != is_active:
            # Only saving the model if we have to
            self.is_active = is_active
            self.save()
Run Code Online (Sandbox Code Playgroud)

然后,您可以创建一个cronjob以每10分钟左右运行一次此命令

*/10 * * * * source /path/to/venv/bin/activate && /path/to/app/manage.py update_active_bookings
Run Code Online (Sandbox Code Playgroud)

无论采用哪种路由,都请确保为开始日期和结束日期都设置了db_index = True,否则这将导致计算量大。