Luv33preet
Luv33preet

Reputation: 1867

django: updating models in the background

I have a model called booking. It has a start_time and an end_time field. It also has a is_active field.

Now, suppose a booking has start_time = 2017/Nov/22 12:00:00 and end_time = 2017/Nov/22 14:00:00.

Now, when the server is ruuning,

1- If current time is between start_time and end_time, then is_active should be True.

2 - current time gets greater than end_time OR less than start_time of a booking, I want to set is_active = False.

I want this to continuously run in the background so that it must keep the booking is_active status real time in the database. How can I do this in django?

Upvotes: 0

Views: 1443

Answers (1)

Robert Townley
Robert Townley

Reputation: 3584

Depending on what your needs are, you might be able to get away with something simpler than using another library or setting up any background tasks.

For example, instead of running a job in the background, you could generate your list of active bookings like this within your view:

from django.utils import timezone

now = timezone.now()
active_bookings = Booking.objects.filter(
    start_time__gte=now,
    end_time__lt=now
)

If you wanted to be able to find out whether an individual booking is active, you could make that a property of the model

# 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)

If you absolutely need it to happen asynchronously (perhaps there's computationally-heavy data operations involved around this) then you can create a management command that updates all objects

# 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()

Then you can create a cronjob to run this command every 10 minutes or so

*/10 * * * * source /path/to/venv/bin/activate && /path/to/app/manage.py update_active_bookings

Whichever route you take, ensure that db_index=True is set for both start and end date, or this will become computationally heavy.

Upvotes: 6

Related Questions