0

如果模型的字段只是一个普通的 ForeignKey,我可以跟踪更改没有问题:

# models.py
class Foo(models.Model):
    history = HistoricalRecords()
    bar = ForeignKey(Bar)

# test.py
b1 = Bar.objects.create()
b2 = Bar.objects.create()
b3 = Bar.objects.create()

foo = Foo.objects.create(bar=b1)
foo.bar = b2
foo.save()
foo.bar = b3
foo.save()

for i in foo.history.all():
    print(i.bar)

# Returns:
# b3
# b2
# b1

但是,如果我的模型是 GenericForeignKey,我会收到以下错误消息:AttributeError: 'HistoricalFoo' object has no attribute 'content_object'

# models.py
class Foo(models.Model):
    history = HistoricalRecords()
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")

# test.py
b1 = Bar.objects.create()
b2 = Bar.objects.create()
b3 = Bar.objects.create()

foo = Foo.objects.create(content_object=b1)
self.assertEqual(foo.content_object, b1) # no problem
foo.content_object = b2
foo.save()
self.assertEqual(foo.content_object, b2) # no problem
foo.content_object = b3
foo.save()
self.assertEqual(foo.content_object, b3) # no problem

for i in foo.history.all():
    print(i.content_object)

# Gives error: AttributeError: 'HistoricalFoo' object has no attribute 'content_object'

然而,django-simple-history 似乎确实跟踪content_typeobject_id更改,所以我可以手动构建content_object

for i in foo.history.all():
    print(i.content_type.model_class().objects.get(pk=i.object_id))

# Returns:
# b3
# b2
# b1

这是唯一/最好/正确的方法吗?

4

0 回答 0