How to Automatically Update Timer Status in Django Upon Duration Expiry?

Hello,

I am working on a habit tracking application in Django + Django Rest. I’ve implemented a feature that includes two types of timers: a stopwatch and a countdown timer. My current challenge is with the countdown timer: I want it to automatically transition its status to ‘stopped’ once the preset duration is reached.

Here is my current model setup:

from django.db import models
from django.utils import timezone
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError

User = get_user_model()

class Habit(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(null=True, blank=True)
    icon = models.CharField(max_length=100, null=True, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

class HabitTimer(models.Model):
    STOPWATCH = "stopwatch"
    TIMER = "timer"
    TIMER_CHOICES = [
        (STOPWATCH, "Stopwatch"),
        (TIMER, "Timer"),
    ]
    STATUS_CHOICES = [
        ('active', 'Active'),
        ('paused', 'Paused'),
        ('stopped', 'Stopped'),
    ]

    habit = models.ForeignKey(Habit, on_delete=models.CASCADE)
    timer_type = models.CharField(max_length=10, choices=TIMER_CHOICES, default=STOPWATCH)
    set_duration = models.DurationField(null=True, blank=True)
    start_time = models.DateTimeField(auto_now_add=True)
    end_time = models.DateTimeField(null=True, blank=True)
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='active')

    def __str__(self):
        return f"{self.habit.name} - {self.timer_type}"

    def clean(self):
        if self.timer_type == self.TIMER and not self.set_duration:
            raise ValidationError("Set duration must be provided for timer type.")

    @property
    def duration(self):
        if self.end_time is None:
            return timezone.now() - self.start_time
        return self.end_time - self.start_time

I am looking for a way to manage the timer’s auto-expiration without having to resort to using Celery or other external task schedulers. The goal is to automatically update the status field from ‘active’ to ‘stopped’ once the set duration is reached. How can I achieve this functionality within Django’s framework?

Any suggestions or guidance on how to implement this feature or pointers to relevant Django features or third-party packages that can help achieve this without significant overhead would be greatly appreciated.

Thank you for your help!

Django is the wrong tool for that. There is no reliable way to do it from within Django itself.

Your easiest-to-implement solution is to use Celery.

Ah, right - thank you, Ken!