我有这样的型号User
:
class User(AbstractBaseUser, PermissionsMixin):
myfield_choices = (('foo', 'First value'), ('bar', 'Second value')
myfield = CharField(choices=choices)
objects = BaseUserManager()
我在字段myfield
中设置了值foo
。在我想在字段myfield
中设置值bar
1天后,并且在该期限到期后,该值再次自动变为foo
如何设置过期时间?有本地django乐器吗?
我认为您对Django有点陌生,所以我建议您使用一种不基于任务队列的解决方案(如celery
或dramatiq
(。
为了清楚起见,让我们假设我们正在实现ban_user
和unban_user
机制。首先,我们必须更新User
模型:
class User(AbstractBaseUser, PermissionsMixin):
class BanStatus(models.TextChoices):
ACTIVE = "ACTIVE", "ACTIVE"
BANNED_FOR_DAY = "BANNED_FOR_DAY", "BANNED_FOR_DAY"
ban_status = models.TextField("Ban status", choices=BanStatus.choices)
banned_for_day_at = models.DateTimeField("Banned for day at", null=True)
然后我们必须实现精确的机制。我更喜欢在一些your-app-name/logic/ban_user.py
文件中进行:
from django.utils import timezone
# And also an import of User.
def ban_user_for_day(user: User):
user.ban_status = User.BanStatus.BANNED_FOR_DAY
user.banned_for_day_at = timezone.now()
user.save()
def revoke_ban_user_for_day(user: User):
user.ban_status = User.BanStatus.ACTIVE
user.banned_for_day_at = None
user.save()
因此,我们可以从视图中调用ban_user_for_day
。对于revoke_ban_user_for_day
,组织调用它的最简单方法是Command
,它可以定期调用,例如cron
。您可以将其放置在your-app-name/management/commands/revoke_ban_user_for_day.py
from django.core.management import BaseCommand
from django.utils import timezone
# And also imports of User and revoke_ban_user_for_day.
class Command(BaseCommand):
def handle(self, *args, **options):
user_list_for_revoke = User.objects.filter(
ban_status=User.BanStatus.ACTIVE,
banned_for_day_at__lte=timezone.now() - timezone.timedelta(days=1)
).all()
for user in user_list_for_revoke:
revoke_ban_user_for_day(user)
仅此而已。如果您将此Command
设置为每分钟运行一次,则User
应取消联机和实际取消联机之间的延迟将不大于1分钟。