我正在使用django-simple-history
:
http://django-simple-history.readthedocs.io/en/latest/
我有一个模型,我想在历史实例上应用它的方法。示例:
from simple_history.models import HistoricalRecords
class Person(models.Model):
firstname = models.CharField(max_length=20)
lastname = models.CharField(max_length=20)
history = HistoricalRecords()
def fullName(self):
return firstname + lastname
person = Person.objects.get(pk=1) # Person instance
for historyPerson in person.history:
historyPerson.fullName() # wont work.
由于类HistoricalPerson不继承Person的方法。但是使用Person方法实际上是有意义的,因为它们共享相同的字段..
任何解决方案?我更喜欢简单的东西,而不是像我的模型中为历史实例复制每个方法。
答案 0 :(得分:1)
我找到了另一个解决方法(也许只是插件已更新并获得了此功能)。它基于文档:adding-additional-fields-to-historical-models
HistoricalRecords
字段接受bases
参数,该参数设置历史对象将继承的类。但是您不能只在bases=[Person]
类描述中设置Person
,因为它尚未初始化。
因此,我最终得到了一个抽象类,该类同时被Person
类和HistoricalRecords
字段所继承。因此,该问题的示例如下所示:
class AbstractPerson(models.Model):
class Meta:
abstract = True
firstname = models.CharField(max_length=20)
lastname = models.CharField(max_length=20)
def fullName(self):
return firstname + lastname
class Person(AbstractPerson):
history = HistoricalRecords(bases=[AbstractPerson])
现在历史记录对象可以使用fullName
方法。
答案 1 :(得分:0)
对于其他遇到同样问题的人,我通过调用历史记录对象上原始类的方法来使其工作。因此,对于问题中的示例,解决方案可能是:
for historyPerson in person.history:
Person.fullName(historyPerson)
这很有效,因为方法与Python中的函数非常相似,只是当您在实例上调用方法时,实例将作为方法的第一个参数隐式传递。所以如果你有一个类:
class Foo:
def method(self):
....
操作
f = Foo()
f.method()
与:
相同f = Foo()
Foo.method(f)
我并不确切知道为什么simple-history
不会复制原始模型的方法。一个原因可能是因为它允许你exclude fields to be recorded,原始方法可能没有意义,因为如果方法使用未记录在历史记录中的字段,则该方法可能不起作用。