你不需要在模型中存储status,你可以简单地.annotate(..) [Django-doc]它,所以如果模型看起来像:
class MyModel(models.Model):
expiration_date = models.DateField(db_index=True)
所以没有 status 字段。然后您可以使用以下方法进行注释:
from django.db.models import BooleanField, ExpressionWrapper, Q
from django.db.models.functions import Now
MyModel.objects.annotate(
satus=ExpressionWrapper(
Q(expiration_date__gt=Now()),
output_field=BooleanField()
)
)
如果expiration_date 在未来,则由此查询集产生的MyModel 对象将具有一个额外的属性.status,即True。
如果你经常需要这个,你可以创建一个manager [Django-doc],它会在你每次访问MyModel.objects时自动注释项目:
from django.db.models import BooleanField, ExpressionWrapper, Q
from django.db.models.functions import Now
class MyModelManager(models.Manager):
def get_queryset(self, *args, **kwargs):
super().get_queryset(*args, **kwargs).annotate(
satus=ExpressionWrapper(
Q(expiration_date__gt=Now()),
output_field=BooleanField()
)
)
class MyModel(models.Model):
expiration_date = models.DateField(db_index=True)
objects = MyModelManager()
这不需要计划任务,这很难管理:如果您稍后编辑expiration_date,那么您需要以某种方式“删除”已计划的任务并安排一个新的任务,这可能是“棘手的” .如果计划任务已经完成,则必须“撤消”它。
通过使用注释,您可以确保 status 仅基于 expiration_date 与 Now() 的值相比。