Django humanize timesince过滤器无输出问题排查
我帮你排查下这个问题,核心原因是时区感知(aware)和无时区(naive)的datetime对象无法被timesince过滤器正确比较,导致没有输出。
问题分析
你在视图里用datetime.now()生成的now_time是一个无时区的naive datetime对象;而你的material.last_update作为Django的DateTimeField,如果项目设置中USE_TZ = True(Django默认开启),它会被存储为带时区的aware datetime对象。
timesince过滤器在处理类型不匹配的datetime时,会静默返回空值——这就是为什么单独显示两个变量都正常,但组合使用没有输出的原因。
另外还有个小细节:Django的timesince过滤器默认会以当前时间作为比较基准,其实你完全不需要手动传递now_time,写法可以更简洁。
解决方案
方案1:修复时区匹配问题
把视图里的datetime.now()替换成Django提供的timezone.now(),它会生成与模型字段匹配的带时区datetime对象:
首先在视图顶部导入工具:
from django.utils import timezone
然后修改context中的now_time:
context={'material': material_id, 'inventory_list': inventory, 'now_time': timezone.now()}
修改后两个datetime都是aware类型,timesince就能正常计算时间差了。
方案2:简化模板代码(更推荐)
直接省略now_time参数,timesince会自动用当前时间做基准,还能自动处理时区问题:
{{ material.last_update|timesince }}
这样你的示例中last_update是10:45、当前时间是11:10的话,会输出25 minutes(或对应语言的本地化结果)。
额外小建议
你的视图里把Material对象赋值给了material_id变量,这个命名容易混淆(看起来像ID值,但实际是对象),建议改成material,代码可读性会更好:
def material_page(request,pk): try: material = Material.objects.get(id=pk) inventory = InventoryMove.objects.filter(material=material).order_by("-date") # 你的循环逻辑... except Material.DoesNotExist: raise Http404("Material does not exist") return render( request, 'material_detail.html', context={'material': material, 'inventory_list': inventory} )
内容的提问来源于stack exchange,提问作者hopieman

