我正在使用django-密克罗尼西亚联邦在一个state字段(FSMField类型)来跟踪一个过程中的样本管。我需要允许一些高级用户将对象从一种状态“跳转”到另一种状态,并在发生时记录和发送通知。我的问题是:如何在避免代码重复(即do )的同时编写这个转换?
更多详细信息:
我已经在我的protected=True上设置了FSMField:我非常喜欢它提供的保护--没有其他代码路径能够改变state。
下面是基本知识(注意:不是完整的代码,不能工作,只是为了说明)
class SampleTube(model.Model):
state = FSMField(default='new', choices=(...), protected=True)
@transition(field=state, source='*', target='*', permission='my_app.superpowers') # <-- problem 1
def set_state(self, user, new_state):
assert is_valid_state(new_state)
log_event(self, user, new_state)
send_notification(self, self.owner)
self.state = new_state # <-- problem 2问题1:据我了解,我只能为target (docs链接)使用一个字符串值。当然可以。我喜欢调用方法模型自动设置state这一事实。所以我不认为我可以写一个过渡到一个任意的状态。
问题2:如果我想保留protected=True (出于上述原因),我不能直接修改state字段(如文档所示,引发AttributeError )。
我必须在我的模型课上写这个吗?有什么元编程方法可以让我保持干燥吗?
@transition(field=state, source='*', target='used', permission='myapp.superpowers')
def set_used(self, user):
# ...
@transition(field=state, source='*', target='received', permission='myapp.superpowers')
def set_received(self, user):
# ...
#... loads more set_xyz methods that all have the same signature...我之所以想解决这个问题(除了对简洁代码的欣赏),是因为潜在状态的数量相当大(10+)。
我突然意识到,在state方法中暂时显式禁用对set_state字段的保护可能是另一种方法,如果我能想出如何.
发布于 2016-02-17 05:25:33
虽然作为django-fsm i的作者,我强烈建议不要使用您的方法,但我认为它最终可能会导致if-elif垃圾在set_state函数中,我可以建议,不要将它作为模型方法来实现。
相反,只需创建一个常规函数,并直接更新db状态。
def set_state(tube, new_state): SampleTube.objects.filter(pk=tube.pk).update(state=new_state);
https://stackoverflow.com/questions/35312226
复制相似问题