从 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
我找不到从 HistoricalChild
到 HistoricalParent
的外键。我错过了什么吗? django-simple-history 是否以其他方式工作?
错误消息对我来说很清楚:没有 child
属性关联到您的 Parent
模型。您不能从 parent
访问 child
,因为它们之间没有关系(从数据库的角度来看)。从父类继承class并不意味着它们之间有任何关系,只是子类将继承父类的属性和方法,仅此而已。
我不确定这是你想要做的,但可以通过反向关系访问对象父对象。
例如,如果您在 Parent
和 Child
之间有一个明确的 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)
我正在尝试使用 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
我找不到从 HistoricalChild
到 HistoricalParent
的外键。我错过了什么吗? django-simple-history 是否以其他方式工作?
错误消息对我来说很清楚:没有 child
属性关联到您的 Parent
模型。您不能从 parent
访问 child
,因为它们之间没有关系(从数据库的角度来看)。从父类继承class并不意味着它们之间有任何关系,只是子类将继承父类的属性和方法,仅此而已。
我不确定这是你想要做的,但可以通过反向关系访问对象父对象。
例如,如果您在 Parent
和 Child
之间有一个明确的 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)