Альтернативный подход - вообще не хранить текущий статус пользователя. Вместо этого, хранить журнал изменений этого статуса и вычислять его текущее значение по требованию. Мне привычно рассуждать в терминах Django, на её ORM и будем ориентироваться. Пусть у вас есть своя собственная модель для пользователя -
User в приложении
my_auth. Пусть у него может быть два значения статуса: пустое (
None) и
premium - для тех, кто оплатил подписку на год. Журнал изменений статуса:
from django.db import models
from my_auth.models import User
class StatusEvent(models.Model):
EVENT_TYPES = [
('subscription', 'User subscribed to premium')
]
user = models.ForeignKey(User, related_name='events')
time = models.DateTimeField(auto_now_add=True)
type = models.CharField(max_length=16, choices=EVENT_TYPES)
class Meta:
ordering = '-time'
Функция вычисления статуса определена в модели
User:
from datetime import datetime
from django.contrib.auth.models import User as DefaultUser
class User(DefaultUser):
@property
def status(self):
event = self.events.filter(type='subscription').first()
if event and datetime.now() - event.time < self.subscription_duration:
return 'premium'
Здесь
subscription_duration - длительность действия подписки, значение типа
datetime.timedelta. Ну или
relativedelta из
dateutil можно использовать, оно удобней. Да, это влечёт постоянные проверки статуса, но не думаю, что это такая уж большая проблема в сравнении с тем, чтоб городить ещё один процесс крона или Celery, чрезмерно усложняя систему.