讲师中心 微信公众号

工具推荐

视频效率加速
剧云
剧云

中文短剧剧本制作平台

Laper
Laper

剧本策划到成片协作

Seko
Seko

AI短剧一键生成成片

立刻MV
立刻MV

低成本歌曲 MV、视频生成

如何在 Django 模板中正确显示模型的时间戳字段

冬涛君_4958

冬涛君_4958

发布时间:2026-02-10 22:43:43

|

713人浏览过

|

来源于php中文网

原创

如何在 Django 模板中正确显示模型的时间戳字段

本文详解 django 中 `datetimefield(auto_now=true)` 字段的正确使用方式,重点解决时间戳无法在模板中显示、被意外覆盖或批量更新的问题,并提供安全、可维护的数据传递方案。

在 Django 开发中,auto_now=True 是一个常用但易被误解的参数。它会在每次模型实例调用 save() 时自动更新为当前时间(等价于 auto_now_add=False, auto_now=True),适用于记录“最后修改时间”。但正如你在实践中遇到的问题所示:若直接在视图中多次调用 .get() 或重复赋值同名变量(如 playinglist = ...),不仅会导致逻辑混乱、数据覆盖,还可能引发 MultipleObjectsReturned 异常或时间戳被意外刷新。

✅ 正确做法:在循环中直接访问实例属性,结构化传递数据

你的原始代码试图在循环外单独查询 started_on,或在循环内错误地覆写 playinglist 变量(如 playinglist = Playinglist.objects.get(...)),这破坏了原始查询集,也违背了 ORM 的设计意图。时间戳是模型实例的固有属性,无需额外查询——只要获取到该实例,即可通过 item.started_on 直接访问。

以下是优化后的视图逻辑(views.py):

# 获取用户当前的 playing 列表
playinglist = Playinglist.objects.filter(user=request.user.username)
playinglist_items = []
present_in_playinglist = False

if playinglist:
    for item in playinglist:
        try:
            game = Game.objects.get(id=item.game_id)
            # ✅ 关键改进:将 game 和时间戳一起封装为字典
            playinglist_items.append({
                'game': game,
                'started_on': item.started_on  # 直接读取已加载实例的字段
            })
            present_in_playinglist = True
        except Game.DoesNotExist:
            # 避免裸 `except:` —— 明确捕获预期异常,防止隐藏 bug
            continue

# 同理处理 playedlist
playedlist = Playedlist.objects.filter(user=request.user.username)
playedlist_items = []
present_in_playedlist = False

if playedlist:
    for item in playedlist:
        try:
            game = Game.objects.get(id=item.game_id)
            playedlist_items.append({
                'game': game,
                'finished_on': item.finished_on
            })
            present_in_playedlist = True
        except Game.DoesNotExist:
            continue

context = {
    "playinglist_items": playinglist_items,
    "playedlist_items": playedlist_items,
    "present_in_playinglist": present_in_playinglist,
    "present_in_playedlist": present_in_playedlist,
    "playing": len(playinglist_items),
    "finished": len(playedlist_items),
}
return render(request, "capstone/profile.html", context)

? 模板渲染:解构字典,精准输出时间戳

在 profile.html 中,你不再需要全局变量 started_on,而是遍历已结构化的 playinglist_items,从中提取每个条目的 game 和对应时间戳:

{% if present_in_playinglist %}
  <h5>Currently Playing</h5>
  {% for entry in playinglist_items %}
    <div class="game-entry">
      <strong>{{ entry.game.title }}</strong>
      <p>Started on: {{ entry.started_on|date:"M d, Y H:i" }}</p>
    </div>
  {% endfor %}
{% else %}
  <h6>No games currently playing.</h6>
{% endif %}

{% if present_in_playedlist %}
  <h5>Completed Games</h5>
  {% for entry in playedlist_items %}
    <div class="game-entry">
      <strong>{{ entry.game.title }}</strong>
      <p>Finished on: {{ entry.finished_on|date:"M d, Y H:i" }}</p><div class="aritcle_card flexRow">
                                                        <div class="artcardd flexRow">
                                                                <a class="aritcle_card_img" href="/xiazai/skill10428" title="Django Wrap"><img
                                                                                src="https://img.php.cn/upload/skill/001/246/273/6adaf20dbae7c507.jpg" alt="Django Wrap" ></a>
                                                                <div class="aritcle_card_info flexColumn">
                                                                        <a href="/xiazai/skill10428" title="Django Wrap">Django Wrap</a>
                                                                        <p>强戈环形山: q15040409-刻画家功能概述强戈环形山: q15040409-刻画家是一项面向实际任务的技能,主要用于平顶山: 维西翁: 1:1.0. 塔格斯: rap.github: 自动化。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。核心要点使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。从功能定位来看,该</p>
                                                                </div>
                                                                <a href="/xiazai/skill10428" title="Django Wrap" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
                                                        </div>
                                                </div>
    </div>
  {% endfor %}
{% else %}
  <h6>No games completed yet.</h6>
{% endif %}
? 提示:Django 模板过滤器 |date:"M d, Y H:i" 可美化时间显示(如 Jun 15, 2024 14:30),避免默认 ISO 格式带来的可读性问题。

⚠️ 重要注意事项与最佳实践

  • 不要滥用 auto_now=True 做“创建时间”用途:auto_now=True 会在每次 save() 时更新,因此不适合记录首次创建时间。若需区分“创建时间”和“更新时间”,应使用:

    created_at = models.DateTimeField(auto_now_add=True)   # 仅创建时设置
    updated_at = models.DateTimeField(auto_now=True)       # 每次 save() 更新
  • 避免裸 except::你的原代码中使用 except: 会捕获所有异常(包括 KeyboardInterrupt),极易掩盖真实错误。始终明确指定异常类型(如 Game.DoesNotExist)。

  • 性能优化建议:当前代码对每个 item.game_id 单独查询 Game,存在 N+1 查询问题。推荐改用 select_related() 或更优的 prefetch_related()(若关系为 ForeignKey)或使用 values_list() + 批量查询。例如:

    game_ids = [item.game_id for item in playinglist]
    games_map = {g.id: g for g in Game.objects.filter(id__in=game_ids)}
    for item in playinglist:
        game = games_map.get(item.game_id)
        if game:
            playinglist_items.append({'game': game, 'started_on': item.started_on})
  • 事务与并发安全:add_to_playinglist 和 add_to_playedlist 中涉及删除与新增操作,建议包裹在 transaction.atomic() 中,防止中间状态不一致。

✅ 总结

时间戳不是“额外数据”,而是模型实例的一等公民。正确的方式是:在查询后直接访问实例字段 → 结构化组装上下文 → 模板中解构渲染。摒弃重复查询、变量覆盖和模糊异常处理,你的代码将更健壮、高效且易于维护。记住:Django ORM 的力量,在于让你专注业务逻辑,而非手动拼接 SQL 或管理时间字段生命周期。

热门AI工具

更多
超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4983

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1011

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1309

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

7041

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

3703

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

7020

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

9821

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1330

2024.04.29

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go-Zero HTTP服务开发指南
Go-Zero HTTP服务开发指南

共0课时 | 0人学习

Go-Zero goctl安装与使用手册
Go-Zero goctl安装与使用手册

共0课时 | 0人学习

Go-Zero框架快速开始指南
Go-Zero框架快速开始指南

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn