从父级到子级历史记录的Django简单历史记录继承

时间:2019-12-25 09:57:01

标签: python django django-models django-simple-history

我正在尝试使用Quickstart: Azure Blob storage client library v8 for Java来保持对象的状态。

假设我有以下内容:

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

如何从InvoiceChild

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

不工作并不能加薪

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

这就是我从ChildParent的方式

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

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

2 个答案:

答案 0 :(得分:0)

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

我不确定这是您要执行的操作,但是可以通过反向关系访问对象父对象。

例如,如果您在ParentChild之间建立了清晰的链接,如下所示:

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')

然后,可以按以下方式访问parentchild.parent(毫不奇怪),但是由于存在逆关系,也可以从parent访问子级(请检查{{1} }参数):related_name

希望有帮助!

答案 1 :(得分:0)

因此,在使用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')

会退回这么多物品,对我来说这毫无用处,因为父母从某个日期开始就拥有状态,但是孩子是从将来开始的

这意味着我无法在某个特定时间通过引用其历史父级来重新创建一个完整的子级。

我最终使用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)