我正在尝试开发一个 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
可以在 a 上处于活动状态。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”对象的交互?
重新阅读上面的内容有点混乱,但这也不是一个简单的话题!!如果有人对如何执行上述操作有任何想法,请告诉我!
万分感谢!