从 parent 到 child 历史的 Django 简单历史继承

Django simple history inheritance getting from parent to child history

我正在尝试使用 django-simple-history 来保持 Object 的状态。

假设我有以下内容:

class Parent(models.Model):
    fields...
    history = HistoricalRecords(inherit=True)

class Child(Parent):
    fields...

class Invoice(models.Model):
    fields...
    parent_history = models.ForeignKey("app.HistoricalParent", blank=True, null=True, on_delete=models.PROTECT, help_text="This keeps the state of the Child when Invoice is generated")
    parent =  models.ForeignKey(Parent, blank=True, null=True, on_delete=models.PROTECT) # can be removed so foreign key loop gets eliminated

我怎样才能从 Invoice 到达 Child

Invoice.objects.get(id=1).parent_history.child

不工作并提高

AttributeError: 'HistoricalParent' object has no attribute 'child'

这就是我从 Parent

到达 Child 的方式
Invoice.objects.get(id=1).parent.child

我找不到从 HistoricalChildHistoricalParent 的外键。我错过了什么吗? django-simple-history 是否以其他方式工作?

错误消息对我来说很清楚:没有 child 属性关联到您的 Parent 模型。您不能从 parent 访问 child,因为它们之间没有关系(从数据库的角度来看)。从父类继承class并不意味着它们之间有任何关系,只是子类将继承父类的属性和方法,仅此而已。

我不确定这是你想要做的,但可以通过反向关系访问对象父对象。

例如,如果您在 ParentChild 之间有一个明确的 link,如下所示:

class Parent(models.Model):
    fields...
    history = HistoricalRecords(inherit=True)

class Child(models.Model):
    fields...
    parent = models.ForeignKey(Parent, blank=True, null=True, on_delete=models.PROTECT, related_name='blabla')

然后,parent 可以按如下方式访问:child.parent(不足为奇),但是由于逆关系(检查 related_name 参数): parent.blabla.

希望对您有所帮助!

所以让我在使用django-simple-history

时打破外键关系

所以 HistoricalChild 没有得到 HistoricalParent

的外键
HistoricalChild = apps.get_model('app', 'HistoricalChild')
HistoricalChild.objects.filter(parent_ptr_id=invoice.parent_history.id).order_by('-history_date')

会 return 这么多项目吗?它对我来说毫无用处,因为 parent 是某个日期的状态,而 child 是未来的

这意味着我无法通过参考某个时间点的历史 parent 来重新创建完整的 child。

我最终使用 historical_date 从某个时间重新创建了一个 Child 实例,就像这样

parent_dict = apps.get_model('order', 'HistoricalParent').objects.filter(history_date__lte=invoice.created_date).order_by('-history_date').values().first()
child_dict = apps.get_model('app', 'HistoricalChild').objects.filter(history_date__lte=invoice.created_date).order_by('-history_date').values().first()

child_dict.update(parent_dict)

for field in ['history_change_reason', 'history_id', 'history_type', 'history_date', 'history_user_id']:
    child_dict.pop(field)

child_from_the_past = Child(**child_dict)