Django用timezone.now()计算到期帖剩余时间如何隐藏毫秒并格式化
解决方案
你遇到的问题核心是remaining_time属于timedelta类型,你之前尝试的所有过滤器都是为datetime对象设计的,自然无法正常工作。这里提供两种可行方案:
方案1:视图层直接格式化(推荐,逻辑更集中)
直接修改views.py的代码,计算出剩余时间后直接格式化好再传给模板:
from django.utils import timezone from datetime import timedelta def blogpost_detail(request,blogpost_id): # 注意你原代码这里有笔误,是get_object_or_404不是get_objects_or_404 blog = get_object_or_404(BlogPost,pk=blogpost_id) remaining_time = blog.blog_date_added - timezone.now() + timedelta(days=2) # 新增格式化逻辑 total_sec = int(remaining_time.total_seconds()) if total_sec <= 0: formatted_remaining = "已过期" else: days = total_sec // 86400 hours = (total_sec % 86400) // 3600 time_parts = [] if days > 0: time_parts.append(f"{days} days") # 剩余不足1天也显示小时数 if hours > 0 or days == 0: time_parts.append(f"{hours} Hours") formatted_remaining = f"{' '.join(time_parts)} Remaining" context = {'remaining_time': formatted_remaining,'blog':blog} # 注意你原代码这里括号写错了,是)不是} return render(request, 'blogpost_detail.html', context)
模板中直接调用即可:
{{ remaining_time }}
方案2:自定义模板过滤器(适合多页面复用的场景)
- 在你的blog应用下新建
templatetags目录,新增__init__.py和time_utils.py两个文件 time_utils.py内容如下:
from django import template register = template.Library() @register.filter def format_remaining(value): total_sec = int(value.total_seconds()) if total_sec <= 0: return "已过期" days = total_sec // 86400 hours = (total_sec % 86400) // 3600 time_parts = [] if days > 0: time_parts.append(f"{days} days") if hours > 0 or days == 0: time_parts.append(f"{hours} Hours") return f"{' '.join(time_parts)} Remaining"
- 模板顶部加载标签:
{% load time_utils %}
- 调用方式:
{{ remaining_time|format_remaining }}
之前方案失败原因说明
- 对
timezone.now()除以1000:该方法是用于整数类型的时间戳格式化,timezone.now()返回的是datetime对象,不支持算术除法操作 time/naturaltime/timesince过滤器:以上过滤器均只接受datetime类型作为输入,你传入的是timedelta类型,所以要么无输出要么报错
内容的提问来源于stack exchange,提问作者Lars
相关产品推荐
相关产品推荐

