首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >你能为一个针对任意状态的django-fsm转换编写代码吗?

你能为一个针对任意状态的django-fsm转换编写代码吗?
EN

Stack Overflow用户
提问于 2016-02-10 10:10:46
回答 1查看 2.9K关注 0票数 3

我正在使用django-密克罗尼西亚联邦在一个state字段(FSMField类型)来跟踪一个过程中的样本管。我需要允许一些高级用户将对象从一种状态“跳转”到另一种状态,并在发生时记录和发送通知。我的问题是:如何在避免代码重复(即do )的同时编写这个转换?

更多详细信息:

我已经在我的protected=True上设置了FSMField:我非常喜欢它提供的保护--没有其他代码路径能够改变state

下面是基本知识(注意:不是完整的代码,不能工作,只是为了说明)

代码语言:javascript
复制
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 )。

我必须在我的模型课上写这个吗?有什么元编程方法可以让我保持干燥吗?

代码语言:javascript
复制
@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字段的保护可能是另一种方法,如果我能想出如何.

EN

回答 1

Stack Overflow用户

发布于 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);

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35312226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档