返回当前项目状态(即Django-Manytomy关系的最近日期) 模式描述
项目的状态可以随时间而改变。为了随时间跟踪状态,我通过返回当前项目状态(即Django-Manytomy关系的最近日期) 模式描述,django,database-design,django-models,database-schema,Django,Database Design,Django Models,Database Schema,项目的状态可以随时间而改变。为了随时间跟踪状态,我通过ProjectStatus中间表在Project模型和ProjectStatusType模型之间创建了多对多关系 虽然这允许随着时间的推移跟踪项目的状态,但它增加了模式的复杂性,因此检索项目的当前状态或检索所有打开的项目更加困难 用例 我希望能够返回处于给定状态的所有项目,例如所有openprojects。例如,当用户转到时,默认情况下,我只希望在表中显示open项目 问题 我是否应该对模式进行反规范化,并在项目模型中添加一个当前状态字段
ProjectStatus
中间表在Project
模型和ProjectStatusType
模型之间创建了多对多关系
虽然这允许随着时间的推移跟踪项目的状态,但它增加了模式的复杂性,因此检索项目的当前状态或检索所有打开的项目更加困难
用例
我希望能够返回处于给定状态的所有项目,例如所有open
projects。例如,当用户转到时,默认情况下,我只希望在表中显示open
项目
问题
项目
模型中添加一个当前状态
字段项目
模型上创建一个检索当前状态的属性根据您的描述,我假设您实际上使用了
ProjectStatus
作为ManyToManyField
的到,并且您已经存储了与该模型的关系的额外数据。如果其中一个额外数据项不是设置该特定状态时的日期时间,我会将其添加到您的模型中
然后,您可以按该日期时间降序订购ProjectStatus
,因此返回的第一个ProjectStatus
将始终是最新的(当前)。根据您的描述,我假设您实际上使用ProjectStatus
作为到的多个域的,而且您已经存储了关于与该模型的关系的额外数据。如果其中一个额外数据项不是设置该特定状态时的日期时间,我会将其添加到您的模型中
然后,您可以按该日期时间降序排列ProjectStatus
,这样返回的第一个ProjectStatus
将始终是最新的(当前)。如果您不需要搜索它,我将在项目模型上创建一个属性。您可以使用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']
这一策略已被记录在案
如果您需要进行查找,那么您应该取消规范化并向项目添加一个字段。你可以用信号保持电流。您需要将post\u 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)
您可以阅读更多有关信号的信息
======
编辑:自从写了我的原始答案后,OP在某种程度上澄清了他的问题,他的澄清改变了我两种策略的示例代码,尽管不是它们的基本结构。我想把最初的答案留给那些可能需要更多类似于我当时想回答的问题的人
在我的第一个例子中,他并不真正想要最新的状态日期本身,而是最新的项目状态类型。这将极大地改变财产;您根本不需要使用MAX()
SQL构造;按日期递减排序时,您只需要将第一条记录附加到此对象:
class Project(models.Model):
[...]
@property
def project_status(self):
return self.status.order_by('-status_date')[0]
与此相关的用例仍然是相同的。如果你总是先得到一个项目,然后想知道它的当前状态,这是正确的方法。如果需要按状态为项目编制索引,则需要取消规范化。这仍然是通过信号来完成的最好方法,但是与我在上面的示例中所做的那样保存日期不同,您可能希望保存一个描述。尽管如此,原理仍然是一样的。如果不需要搜索,我会在项目模型上创建一个属性。您可以使用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']
这一策略已被记录在案
如果您需要进行查找,那么您应该取消规范化并向项目添加一个字段。你可以用信号保持电流。您需要将post\u 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)
您可以阅读更多有关信号的信息
======
编辑:自从写了我的原始答案后,OP在某种程度上澄清了他的问题,他的澄清改变了我两种策略的示例代码,尽管不是它们的基本结构。我想把最初的答案留给那些可能需要更多类似于我当时想回答的问题的人
在我的第一个例子中,他并不真正想要最新的状态日期本身,而是最新的项目状态类型。这将极大地改变财产;您根本不需要使用MAX()
SQL构造;按日期递减排序时,您只需要将第一条记录附加到此对象:
class Project(models.Model):
[...]
@property
def project_status(self):
return self.status.order_by('-status_date')[0]
与此相关的用例仍然是相同的。如果你总是先得到一个项目,然后想知道它的当前状态,这是正确的方法。如果需要按状态为项目编制索引,则需要取消规范化。这仍然是通过信号来完成的最好方法,但是与我在上面的示例中所做的那样保存日期不同,您可能希望保存一个描述。原理仍然是一样的。完全不相关,但是您是手工创建图像的,还是有某种自动工具根据您的模型创建图像的。这似乎是这样的,因为它匹配从Django网站和管理员的配色方案。。。如果是这样的话,我想使用这个工具:)@jro:I使用OSX上的OmngiGraffle Professional创建带有从下载的Django绘图模具的绘图