为了跟踪我的一些Django项目模型,我需要实现一个有限状态机器。我已经有一个类似的应用程序,但它与其他应用程序模型密切相关,不能以任何方式重用。所以我决定重新考虑它。需要一些关于为Django编写可重用应用程序的建议
几个小时后,这是我想出了:
class StateMachine(models.Model):
name = models.CharField(max_length=50, help_text="Must be an unique name")
template = models.BooleanField(default=True)
current_state = models.ForeignKey('State', blank=True, null=True, related_name='current_state')
initial_state = models.ForeignKey('State', blank=True, null=True, related_name='initial_state')
def get_valid_actions(self):
return Action.objects.filter(machine=self, from_state=self.current_state)
def copy(self):
...
class State(models.Model):
name = models.CharField(max_length=50)
machine = models.ForeignKey(StateMachine)
def enter_hook(self, machine=None, action=None, state=None):
pass
def exit_hook(self, machine=None, action=None, state=None):
pass
def _copy(self, machine):
...
class Action(models.Model):
name = models.CharField(max_length=50)
machine = models.ForeignKey(StateMachine)
from_state = models.ForeignKey(State, related_name='from_state')
to_state = models.ForeignKey(State, blank=True, null=True, related_name='to_state')
def is_valid(self):
if self.machine.current_state == self.from_state:
return True
else:
return False
def act(self):
if self.is_valid():
self.from_state.exit_hook(machine=self.machine, action=self, state=self.from_state)
self.machine.current_state = self.to_state
self.machine.save()
self.to_state.enter_hook(machine=self.machine, action=self, state=self.to_state)
else:
raise ActionNotApplicable()
return self.machine
def _copy(self, machine):
...
我很满意的结果。它完成状态机所要做的事情,而不是别的。在我的模型,我使用它是这样的:
class SampleModel(models.Model):
machine = models.ForeignKey(StateMachine, null=True)
def setup_machine(self):
self.machine = StateMachine.objects.get(template=True, name='bla bla bla').copy()
self.save()
我基本上使用管理界面创建一个“模板”的机器,然后我运行的复制状态机模型,并设置该模板为False复制方法。
现在,这才是我的问题:)
是利用相同的SampleModel一个ForeignKey附加 的的StateMachine它的最佳方式?我读过关于Django中的泛型关系的 ,但我以前从未使用过 。在我的情况下使用它会有好处吗?
我试图遵循“做一件事 并把它做好”的理念, 但我有其他业务 需求来实现。例如,对于 示例,每次状态发生更改时,我都需要发送一封电子邮件给特定的组,并且此组的状态各不相同。我提出的第一个解决方案是在状态模型中添加一个“email”字段。但是这会违反这个应用程序要做的事情,这只是为了跟踪状态机。解决这个问题最好的办法是什么?
我还包括在 模型一些钩子函数,这样后来有人可能 将自定义的行为,这是 做到这一点的最好方法是什么? (我认为 Django已经是一个信号系统)
其他的想法/评论?我是新来 这种可重复使用的应用程序的事情:)
谢谢!
我想在我的情况下,在数据库中存储所有内容是必要的。了解国家有帮助,但并不能解决我所有的问题。例如,我想能够将特定状态链接到用户,以便用户在状态更改时接收更新。 – 2010-07-15 15:06:14
我认为它不会改变任何事情:检查我的编辑... – sebpiq 2010-07-15 15:38:15
谢谢!我会检查代码:) – 2010-07-15 20:14:23