如何设置字段值过期时间?
How to set field value expiration time?
我有这样的模型 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 分钟.
我有这样的模型 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 分钟.