项目的状态可能会随时间而变化。为了跟踪一段时间内的状态,我通过Project
中间表在ProjectStatusType
模型和ProjectStatus
模型之间创建了多对多关系。
虽然这允许跟踪项目的状态,但它增加了模式的复杂性,因此检索项目的当前状态或检索所有打开的项目更加困难。
我希望能够返回所有处于给定状态的项目,例如所有open
个项目。例如,当用户转到http://www.example.com/projects时,我希望默认情况下只有open
项目显示在表格中。
current_status
模型中添加Project
字段吗?Project
模型上创建一个检索当前状态的属性吗?答案 0 :(得分:1)
如果您不需要搜索它,我会在Project模型上创建一个属性。您可以使用Max
功能aggregate
来获取最新日期的记录。
from django.db.models import Max
class Project(models.Model):
[...]
@property
def status_date(self):
return self.projectstatus_set.aggregate(newest=Max('status_date'))['newest']
此战略记录在案here。
如果您需要进行查找,则应对其进行非规范化并向Project
添加字段。您可以使用信号使其保持最新状态。您可能希望在post_save
字段中添加ProjectStatus
侦听器,这会将其项目的日期设置为状态'。
from django.db.signals import post_save
def update_status_date(sender, instance=None, **kwargs):
project = instance.project
project.status_date = max(project.status_date, instance.status_date)
project.save()
post_save.connect(update_status_date, sender=ProjectStatus)
您可以阅读有关信号here的更多信息。
==
编辑:自从写完我原来的答案后,OP已经稍微澄清了他的问题,他的澄清改变了我的两个策略的示例代码,尽管不是他们的基本结构。对于那些可能需要更多类似于我认为我当时正在回答的问题的人,我想留下原始答案。在我的第一个例子中,他并不真正想要最新的status_date本身,而是最新的项目状态类型。这将大大改变财产;您根本不需要使用MAX()
SQL构造;你只想要按日期降序排序时附加到这个对象的第一条记录:
class Project(models.Model):
[...]
@property
def project_status(self):
return self.status.order_by('-status_date')[0]
围绕这个的用例仍然是相同的。如果你总是首先得到一个项目,然后想知道它的当前状态,这是正确的方法。如果您需要按状态索引项目,则需要进行非规范化。这仍然是通过信号完成的,但不是像我上面的示例中那样保存日期,您可能想要保存描述。但原则仍然是相同的。
答案 1 :(得分:0)
根据您的描述,我假设您实际上使用ProjectStatus
作为through
的{{1}},并且您已经存储了关于此关系的额外数据那个模特。如果其中一项额外数据尚未设置该特定状态的日期时间,我会将其添加到您的模型中。
然后,您可以按日期时间降序ManyToManyField
,降序,这样返回的第一个ProjectStatus
将始终是最新的(当前)。