我正在尝试开发一个Django应用程序,该应用程序具有围绕对象的时间状态的内置逻辑。期望能够具有表示资源的单个对象,同时具有该资源的属性能够随时间变化。例如,理想的用例是在任何给定时间(去年,昨天,明天,明年……)查询资源的owner
。
这就是我正在工作的...
class Resource(models.Model):
id = models.AutoField(primary_key=True)
class ResourceState(models.Model):
id = models.AutoField(primary_key=True)
# Link the resource this state is applied to
resource = models.ForeignKey(Resource, related_name='states', on_delete=models.CASCADE)
# Track when this state is ACTIVE on a resource
start_dt = models.DateTimeField()
end_dt = models.DateTimeField()
# Temporal fields, can change between ResourceStates
owner = models.CharField(max_length=100)
description = models.TextField(max_length=500)
我觉得我将不得不创建一个自定义界面来与该状态进行交互。一些示例用例(界面完全开放)...
# Get all of the states that were ever active on resource 1 (this is already possible)
Resource.objects.get(id=1).states.objects.all()
# Get the owner of resource 1 from the state that was active yesterday, this is non-standard behavior
Resource.objects.get(id=1).states.at(YESTERDAY).owner
# Create a new state for resource 1, active between tomorrow and infinity (None == infinity)
# This is obviously non standard if I want to enforce one-state-per-timepoint
Resource.objects.get(id=1).states.create(
start_dt=TOMORROW,
end_dt=None,
owner="New Owner",
description="New Description"
)
我觉得创建创建所需的定制逻辑量最大。 我要强制在任何给定时间点在ResourceState
上只有一个Resource
处于活动状态。这意味着要创建一些ResourceState
对象,我需要调整/删除其他人。
>> resource = Resource.objects.get(id=1)
>> resource.states.objects.all()
[ResourceState(start_dt=None, end_dt=None, owner='owner1')]
>> resource.states.create(start_dt=YESTERDAY, end_dt=TOMORROW, owner='owner2')
>> resource.states.objects.all()
[
ResourceState(start_dt=None, end_dt=YESTERDAY, owner='owner1'),
ResourceState(start_dt=YESTERDAY, end_dt=TOMORROW, owner='owner2'),
ResourceState(start_dt=TOMORROW, end_dt=None, owner='owner1')
]
我知道我将不得不围绕定义逻辑进行大部分工作,但是应该在任何直观的地方放置它吗? Django是否为我提供了方便的位置来创建这些方法?如果是这样,在哪里应用它们的最佳位置?针对Resource
对象?使用自定义Manager
处理与相关“ ResourceState”对象的交互?
重新阅读上面的内容有点令人困惑,但这也不是一个简单的话题!!请让我知道是否有人对上述方法有任何想法!
一吨!
答案 0 :(得分:1)
评论太久了,纯粹是一些想法,不是完整的答案,但是已经处理了金融系统中许多有效日期记录(在Django中不是),想到了一些事情:
我的直觉是将其放在资源模型的save方法上。您可能还需要定制管理器。
我可能还会对状态模型中的is_current布尔字段的想法调情,但是将来日期有效的状态记录需要考虑某些注意事项。如果一次只有一个活动状态,我还将检查是否需要结束日期。同时具有开始和结束绝对可以简化原始sql查询(如果需要的话):date() between state.start and state.end
<-这将提供当前记录,任意日期的sub即可获取该日期的有效记录。另外,在您不知道结束日期的情况下,请考虑开放结束日期。您的查询将必须正确处理空值。您可能还需要考虑开放结束日期(例如,对于未知起始日期的大量历史数据)。我建议您不要使用某些超级早期日期作为填充(对于未知的结束日期,该日期与将来的日期相同)-如果您进行大量交易,则查询优化器可能会谢谢您,但是,我可能会变老了,这不再重要了。
如果您想了解这些内容,我建议您浏览https://www.amazon.ca/Art-SQL-Stephane-Faroult/dp/0596008945/和第6章中的1.8:
“但是在解决一个解决方案之前,我们必须承认 评估表有各种形状和大小。例如, 处理大量数据的电信公司拥有 相对短的价格表,不会经常更改。通过 相比之下,一家投资银行会存储所有证券的新价格, 衍生产品以及它可能处理的任何类型的金融产品 几乎连续。在一种情况下,好的解决方案并不一定 成为另一个很好的解决方案。
处理累积和更改的数据需要非常小心 设计和策略随变化率而变化。”