Джанго простая история - используя методы модели?
Я использую 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 на самом деле имеет смысл, поскольку они имеют одни и те же поля..
Любое решение для этого? Я бы предпочел что-то простое, а не дублирование каждого метода в моих моделях для экземпляров истории.
1 ответ
Я нашел другой обходной путь (возможно, просто аддон обновился и получил эту функцию). Это основано на документации: добавление дополнительных полей в исторические модели
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
метод.
Для тех, у кого есть такая же проблема, я заставил ее работать, вызвав метод из исходного класса для объекта исторической записи. Таким образом, для примера в вопросе решение может быть:
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
не копирует методы оригинальной модели. Одна из причин может заключаться в том, что, поскольку он позволяет исключать поля для записи, использование оригинальных методов может не иметь смысла, поскольку метод может не работать, если он использует поля, которые не записаны в хронологической записи.