你能制作一个在 Django 中删除自身的对象吗?

Can you make an objects that deletes itself in Django?

所以我制作了模型VerificationToken

class VerificationToken(models.Model):

    user = models.ForeignKey(User, on_delete=models.CASCADE)
    code = models.CharField(max_length=4)
    date_created = models.DateTimeField(auto_now_add=True)


    @property
    def expiration(self):

        lifetime = timedelta(minutes=10)

        expire = self.date_created + lifetime

        return expire

并且此模型有有效期 属性。有没有办法让这个模型过期后自行删除?

我相信 Django 不提供那种功能。您可以使用 Celery 创建一个 celery 任务,该任务将删除在一定时间后过期的令牌。您还可以创建定期查找过期令牌并将其删除的任务。

Celery documentation

很遗憾,这是不可能的。您可以做的是使用 celery-beat 或您喜欢的方式创建一个 cronjob,并设置一个 cronjob 任务来清理过期的数据库记录(每个 minute/hour/day 一次)

只需制作一个过滤器以防止检索过期的 VerificationTokens:

from datetime import timedelta
from django.db.models.functions import Now

VerificationToken.objects.filter(
    <strong>date_created__gte=Now()-timedelta(minutes=10)</strong>
)

您也可以创建一个管理器,使得 VerificationToken.objects 是一个仅包含 non-expired 个令牌的管理器:

from datetime import timedelta
from django.conf import settings
from django.db.models.functions import Now

class <strong>VerificationTokenManager</strong>(models.Manager):
    
    def get_queryset(self):
        return super().get_querset().filter(
            date_created__gte=Now()-timedelta(minutes=10)
        )

class VerificationToken(models.Model):
    user = models.ForeignKey(
        <strong>settings.AUTH_USER_MODEL</strong>,
        on_delete=models.CASCADE
    )
    code = models.CharField(max_length=4)
    date_created = models.DateTimeField(auto_now_add=True<strong>, db_index=True</strong>)
    objects = <strong>VerificationTokenManager()</strong>

然后您可以创建一个 management command [Django-doc],例如 运行 通过 cron,或其他一些删除过期 VerificationToken 的调度任务:

# app_name/management/commands/remove_expired_tokens.py

from datetime import timedelta
from django.core.management.base import BaseCommand
from django.db.models.functions import Now
from <em>app_name</em>.models import VerificationToken

class Command(BaseCommand):
    help = 'Remove expired verification tokens'

    def handle(self, *args, **options):
        VerificationToken._base_manager.filter(
            <strong>date_created__lt=Now()-timedelta(minutes=10)</strong>
        )<strong>.delete()</strong>

Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.