如何为Django QuerySet添加「是否超过指定天数」的布尔值注解?
解决方法
你之前的代码存在两个关键问题:
- 字段名错误:模型里的发布时间字段是
published,但你误用了F("start"),会导致字段不存在的异常; - 时间计算逻辑的执行层面错误:使用Python端的
timezone.now()会在应用层计算时间,而非数据库层面,可能引发时区偏差或查询过程中时间不一致的问题。
以下是两种正确的实现方式,完成后即可在模板中通过article.is_relevant访问标记结果:
方法一:使用ExpressionWrapper(简洁写法)
from django.db.models import BooleanField, ExpressionWrapper, F from django.db.models.functions import Now from django.utils import timezone Article.objects.annotate( is_relevant=ExpressionWrapper( # 逻辑:发布时间在2年内则标记为True(可根据需求调整比较符号) F('published') >= Now() - timezone.timedelta(days=365*2), output_field=BooleanField() ) )
方法二:使用Case/When(可读性更强)
如果后续需要扩展多分支逻辑,这种写法更易维护:
from django.db.models import BooleanField, Case, When, Value from django.db.models.functions import Now from django.utils import timezone Article.objects.annotate( is_relevant=Case( When(published__gte=Now() - timezone.timedelta(days=730), then=Value(True)), default=Value(False), output_field=BooleanField() ) )
逻辑调整说明
Now()是Django提供的数据库端函数,会直接使用数据库的当前时间,比应用层的timezone.now()更准确;- 若你需要标记2年前及更早发布的文章为
is_relevant=True,只需将比较符号改为<=或<即可。
内容的提问来源于stack exchange,提问作者Daniel Quinn
相关产品推荐
相关产品推荐

