Джанго простая история - используя методы модели?

Я использую 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 не копирует методы оригинальной модели. Одна из причин может заключаться в том, что, поскольку он позволяет исключать поля для записи, использование оригинальных методов может не иметь смысла, поскольку метод может не работать, если он использует поля, которые не записаны в хронологической записи.

Другие вопросы по тегам