重写模型保存方法以自动存储更新字段的以前值

2024-04-16 09:25:20 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有许多记录值的探针。我想建立Django模型来表示探针以及它们记录的测量值。所以像这样的方法是可行的:

class Probe(models.Model):
    name = models.CharField(max_length=256)

    def __unicode__(self):
        return u'<Probe: %s>' % self.name

class Observation(models.Model):
    probe = models.ForeignKey(Probe)
    obstime = models.DateTimeField()
    # the above field should be understood to represent the time in the world
    # represented by the measurement value recorded.  *not* the time at which
    # that value was written to the database.
    value = models.FloatField()

    class Meta:
        unique_together = (('probe', 'obstime'), )

    def __unicode__(self):
        tup = (self.probe.name,
               self.obstime.strftime('%Y%m%d-%H%M%S'),
               '%0.2f' % self.value)
        return u'<Observation: %s @ %s = %s>' % tup

但除此之外,我真的希望我的数据库和应用程序能够跟踪更多的信息。特别是,我真的希望Observation模型有3个附加字段:db_recording_timeprevious_valueprevious_db_recording_time。我希望用户直接尝试操作上面给出的条目,但是让其他字段以预期的方式自动运行。我认为这应该可以通过重写Observation类上的save方法来实现,但是我需要一些帮助!你知道吗

假设一个人在1月5日中午从野外回来,坐在电脑前。他们想记录一些(以前从未输入过)数据,表明ProbeA在1月1日凌晨2点读取了3.14。我只想让他们指定3.14和2AMJan1st,但我想在DB中输入一个观察值:

probe: ProbeA, 
obstime: 2AMJan1st, 
value: 3.14,
db_recording_time: NoonJan5th,
previous_value: Null, 
previous_db_reording_time: Null

然后,几个小时后(2PMJan5th),同一个人可以看到他们的笔记本,并意识到“哦,我误读了我笔记本中的价值…它真的是2.14”。所以我希望他们(使用admin或Python控制台)调用现有的观察结果,并将3.14改为2.14。当他们这么做的时候,我希望DB中的观察结果显示:

probe: ProbeA, 
obstime: 2AMJan1st, 
value: 2.14,
db_recording_time: 2PMJan5th,
previous_value: 3.14, 
previous_db_reording_time: NoonJan5th

我觉得这应该是非常简单的,在管理接口中有一些只读字段的组合,以及在Observation类的save方法中有一些合理的重写。任何帮助都将不胜感激!你知道吗


Tags: the方法selfdbtimevaluemodels记录
1条回答
网友
1楼 · 发布于 2024-04-16 09:25:20

您可以在保存之前从数据库中检索旧记录:

recording_time = models.DateTimeField(auto_now=True)
previous_value = models.FloatField(null=True, default=None)
previous_recording_time = models.DateTimeField(null=True, default=None)

def save(self, force_insert=False, force_update=False, using=None,
         update_fields=None):
    try:  
        obj = Observation.objects.get(pk=self.pk)  
        # this is the record of this instance before editing
    except Observation.DoesNotExist:  # self.pk==None: this is a new Observation
        pass
    else:  #  this is indeed an update
        self.previous_value = obj.value
        previous_db_recording_time = obj.db_recording_time
    super(Observation, self).save(force_insert=force_insert, force_update=force_update, using=using,
         update_fields=update_fields)

现在,任何人都不应该手动设置recording_timeprevious_valueprevious_recording_time。因此可以从ModelForm中排除这些字段,这些字段在ObservationAdmin类中使用。你知道吗

相关问题 更多 >