如果模型的字段只是一个普通的 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_type
和object_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
这是唯一/最好/正确的方法吗?