Django:创建发布/最后编辑字段及解决时间精度对比问题
解决Django模板中判断文章是否编辑过的最优方案
方案1:模型层添加属性(推荐)
在文章模型中封装时间对比逻辑为只读属性,实现一次编写、全项目复用:
from django.db import models from django.utils import timezone class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() published_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @property def has_been_edited(self): # 截断微秒,忽略Django时间精度带来的无意义差异 published_truncated = self.published_at.replace(microsecond=0) updated_truncated = self.updated_at.replace(microsecond=0) return published_truncated != updated_truncated
模板中直接调用该属性,代码简洁无冗余:
<p>发布时间: {{ article.published_at|date:"Y-m-d H:i:s" }}</p> {% if article.has_been_edited %} <p>最后编辑: {{ article.updated_at|date:"Y-m-d H:i:s" }}</p> {% endif %}
若多个模型需要此逻辑,可抽成抽象基类供其他模型继承:
class TimeStampedModel(models.Model): published_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @property def has_been_edited(self): published_truncated = self.published_at.replace(microsecond=0) updated_truncated = self.updated_at.replace(microsecond=0) return published_truncated != updated_truncated class Meta: abstract = True # 文章模型继承抽象基类 class Article(TimeStampedModel): title = models.CharField(max_length=200) content = models.TextField()
方案2:自定义模板过滤器
不想修改模型时,可通过模板过滤器封装对比逻辑:
- 在APP目录下创建
templatetags文件夹(需包含__init__.py),新建article_tags.py:
from django import template register = template.Library() @register.filter def is_edited(published_at, updated_at): # 截断微秒后对比 return published_at.replace(microsecond=0) != updated_at.replace(microsecond=0)
- 模板中加载并使用过滤器:
{% load article_tags %} <p>发布时间: {{ article.published_at|date:"Y-m-d H:i:s" }}</p> {% if article.published_at|is_edited:article.updated_at %} <p>最后编辑: {{ article.updated_at|date:"Y-m-d H:i:s" }}</p> {% endif %}
方案3:优化时间字段存储逻辑
若项目允许,可在模型保存时确保创建阶段updated_at与published_at完全一致,后续仅在内容修改时更新updated_at:
class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() published_at = models.DateTimeField(auto_now_add=True) # 去掉auto_now,改为手动控制更新时间 updated_at = models.DateTimeField(default=timezone.now) def save(self, *args, **kwargs): if not self.pk: # 首次创建文章时 self.updated_at = self.published_at # 可选:仅当内容修改时才更新updated_at if self.pk: original = Article.objects.get(pk=self.pk) if original.content != self.content: self.updated_at = timezone.now() super().save(*args, **kwargs)
此方案下可直接在模板中对比两个时间,无需截断微秒。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

