Django中任务预估完成日期修改时留存历史记录并新增新日期的实现方案
Django任务预估日期历史留存可行方案
针对你需要留存所有历史预估完成日期的需求,推荐以下两种实现方式:
方案1:独立关联模型(优先推荐,符合数据库设计规范)
这种方式结构清晰,支持对历史预估日期做查询、统计、筛选等数据库级操作,扩展性强,还可以额外存储延期原因、修改人、修改时间等附加信息。
实现代码
首先新增历史预估日期的关联模型,和原有的KraBasedOnIo模型做一对多关联:
from django.db import models """Creating KRA Based on Institutional Objectives""" class KraBasedOnIo(models.Model): io = models.ForeignKey(InstitutionalObjectives, on_delete=models.CASCADE, related_name='kra_io') kra_title = models.CharField(max_length = 200) kra_description = models.TextField() kra_target = models.CharField(max_length=200) kra_added_date = models.DateTimeField(auto_now_add=True) # 可以保留该字段存储最新预估日期,方便直接查询 latest_estimated_date = models.DateField(null=True, blank=True) # 新增的预估日期历史模型 class EstimatedDateHistory(models.Model): kra = models.ForeignKey(KraBasedOnIo, on_delete=models.CASCADE, related_name='estimated_date_history') # 历史预估日期 estimated_date = models.DateField() # 记录该预估日期的设置时间 change_date = models.DateTimeField(auto_now_add=True) # 可选:存储延期原因 change_reason = models.TextField(blank=True, default='') class Meta: # 按设置时间倒序,方便直接取最新的日期 ordering = ['-change_date']
常用操作示例
- 新增/修改预估日期时,同时写入历史表和更新最新日期字段:
# 假设kra实例为当前操作的任务对象,new_date为用户提交的新预估日期 EstimatedDateHistory.objects.create(kra=kra, estimated_date=new_date, change_reason=reason) kra.latest_estimated_date = new_date kra.save()
- 模板中展示所有历史预估日期:
<ul> {% for history in kra.estimated_date_history.all %} <li>预估日期:{{ history.estimated_date|date:"Y-m-d" }},设置时间:{{ history.change_date|date:"Y-m-d H:i" }} {% if history.change_reason %},原因:{{ history.change_reason }}{% endif %}</li> {% endfor %} </ul>
方案2:JSONField存储(适合轻量场景,无复杂查询需求)
Django 3.1及以上版本已经原生支持跨数据库的JSONField,你之前使用失败大概率是操作逻辑错误,该字段可以直接存储日期列表满足需求。
实现代码
class KraBasedOnIo(models.Model): io = models.ForeignKey(InstitutionalObjectives, on_delete=models.CASCADE, related_name='kra_io') kra_title = models.CharField(max_length = 200) kra_description = models.TextField() kra_target = models.CharField(max_length=200) kra_added_date = models.DateTimeField(auto_now_add=True) # 存储所有历史预估日期,默认是空列表,列表中第一个元素为初始日期,最后一个为最新日期 estimated_dates = models.JSONField(default=list)
常用操作示例
- 新增预估日期:
# 第一次设置初始日期 kra.estimated_dates.append(str(initial_date)) kra.save() # 延期新增新的预估日期 kra.estimated_dates.append(str(new_extended_date)) kra.save()
- 模板中展示:
<p>初始预估日期:{{ kra.estimated_dates.0 }}</p> <p>所有历史预估日期:</p> <ul> {% for date in kra.estimated_dates %} <li>{{ date }}</li> {% endfor %} </ul>
该方案的缺点是无法直接对存储的日期做数据库级的筛选、排序、统计操作,仅适合简单的存储展示场景。
如果你使用的是PostgreSQL数据库,也可以选择ArrayField(models.DateField())直接存储日期列表,不需要转字符串,但兼容性较差,仅支持PostgreSQL,不做优先推荐。
内容的提问来源于stack exchange,提问作者Devtue
相关产品推荐
相关产品推荐

