返回当前项目状态(即 Django ManyToMany 关系的最新日期)
架构描述
项目的状态可能会随着时间的推移而改变。为了跟踪一段时间内的状态,我通过 ProjectStatus
Project 模型和 ProjectStatusType
模型之间创建了多对多关系代码>中间表。
虽然这允许随着时间的推移跟踪项目的状态,但它增加了模式的复杂性,使得检索项目的当前状态或检索所有打开的项目变得更加困难。
用例
我希望能够返回处于给定状态的所有项目,例如所有 <代码>打开项目。例如,当用户访问 http://www.example.com/projects 时,我会就像默认情况下仅在表格中显示打开
项目一样。
问题
- 我是否应该对架构进行非规范化并在
Project
模型中添加current_status
字段? - 如果我不应该反规范化,我应该使用什么策略来检索每个项目的当前状态?我应该在
Project
模型上创建一个属性来检索当前状态吗?
Schema Description
A project's status can change over time. In order to track the status over time, I've created a many-to-many relationship between the Project
model and the ProjectStatusType
model through the ProjectStatus
intermediary table.
While this allows tracking a project's status over time, it increases the complexity of the schema such that retrieving the current status of a project or retrieving all open projects is more difficult.
Use Case
I want to be able to return all projects that are in a given state, such as all open
projects. For instance, when users go to http://www.example.com/projects, I'd like only the open
projects to be displayed in a table by default.
Questions
- Should I denormalize the schema and add a
current_status
field in theProject
model? - If I shouldn't denormalize, what strategy should I use to retrieve the current status for each project? Should I create a property on the
Project
model that retrieves the current status?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您不需要搜索它,我会在项目模型上创建一个属性。您可以使用
Max
函数进行聚合
来获取最新日期的记录。此策略记录在此处。
如果您需要进行查找,那么您应该反规范化并向
Project
添加一个字段。您可以使用信号使其保持最新状态。您需要向ProjectStatus
字段添加一个post_save
侦听器,这会将其项目的日期设置为“状态”。您可以在此处了解有关信号的更多信息。
======
编辑:自从写下我原来的答案以来,OP 已经在一定程度上澄清了他的问题,他的澄清改变了我的两种策略的示例代码,尽管不是它们的基本结构。我想把原来的答案留给那些可能需要更多类似于我当时想回答的问题的人。
在我的第一个示例中,他实际上并不想要最新的 status_date 本身,而是想要最新的项目状态类型。这将极大地改变财产;您根本不需要使用
MAX()
SQL 构造;您只希望按日期降序排列时附加到该对象的第一条记录:围绕此的用例仍然相同。如果您总是先获得一个项目,然后想了解其当前状态,那么这是正确的方法。如果您需要按状态对项目进行索引,那么您需要非规范化。这仍然最好通过信号来完成,但您可能想保存描述,而不是像我在上面的示例中所做的那样保存日期。但原理仍然是一样的。
If you don't need to search on it, I would create a property on the Project model. You can use the
Max
function toaggregate
to get the record with the newest date.This strategy is documented here.
If you need to do lookups, then you should denormalize and add a field to
Project
. You can keep it current using signals. You would want to add apost_save
listener to yourProjectStatus
field, which would set its project's date to the status'.You can read more about signals here.
======
EDIT: Since writing my original answer, the OP has clarified his question somewhat, and his clarification alters the example code for both of my strategies, although not their basic construction. I want to leave the original answer for those who may have needs more akin to the question I thought I was answering at the time.
In my first example, he doesn't really want the newest status_date itself, but rather the newest project status type. This would change the property substantially; you don't need to use a
MAX()
SQL construct at all; you just want the first record attached to this object when ordered by date descending:The use cases around this are still the same. If you will always get a project first and then want to know its current status, this is the right way to go about it. If you need to index projects by status, then you need to denormalize. This is still best done through signals, but instead of saving the date like I was doing in my example above, you probably want to save a description. The principle remains the same, though.
根据您的描述,我假设您实际上正在使用
ProjectStatus
作为ManyToManyField
的through
,并且您已经在存储有关与该模型关系的额外数据。如果额外数据项之一还不是设置该特定状态时的日期时间,我会将其添加到您的模型中。然后,您可以按该日期时间降序对
ProjectStatus
进行排序,因此返回的第一个ProjectStatus
将始终是最新的(当前)。By your description, I'm assuming you're in fact using
ProjectStatus
as thethrough
for yourManyToManyField
, and that you're already storing extra data on the relationship with that model. If one of the items of extra data is not already the datetime when the that particular status was set, I would add that to your model.You can then order
ProjectStatus
by that datetime, descending, so the firstProjectStatus
returned will always be the most recent (current).