python - Django FSM 状态转换错误

标签 python django fsm

from datetime import datetime

from django.db import models
from django_fsm import FSMField, transition

class Network(models.Model):
    name = models.CharField(max_length=100, unique=True)    
    prefix = models.CharField(max_length=20, default='')
    country = models.CharField(max_length=50, default='')
    client_wsdl = models.TextField(blank=True, default='')

    class Meta:
        db_table = 'network'

    def __unicode__(self):
        return u'{0}'.format(self.name)


class SmsMessage(models.Model):
    #Define State Machine
    received, started, failed, submitted, completed = "received", "started", "failed", "submitted", "completed"
    STATE_CHOICES = (
        (received, received),
        (started, started),
        (failed, failed),
        (submitted, submitted),
        (completed, completed),
    )

    message_id = models.CharField(max_length=50)
    sender_id = models.CharField(max_length=50, default='')
    msisdn = models.CharField(max_length=50)
    message = models.CharField(max_length=200)
    priority = models.CharField(max_length=50)
    status = models.CharField(max_length=20, default='')    
    state = FSMField(default=received, choices=STATE_CHOICES, protected=True)
    callback = models.CharField(max_length=200, default='')
    network = models.ForeignKey(Network, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    modified_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'sms_message'

    def __unicode__(self):
        return self.message_id

    @transition(field=state, source='received', target=started)
    def started(self):
        '''
        Change message request to started state.
        '''        
        return

    @transition(field=state, source='started', target=failed)
    def failed(self):
        '''
        For started requests that cannot be submitted to Network
        hence in a failed state.
        '''
        return

    @transition(field=state, source=started, target=submitted)   
    def submitted(self):
        '''
        Change message request to submitted state.
        '''
        return

    @transition(field=state, source='submitted', target=completed)
    def completed(self):
        '''
        Request was sucessfully submited to mno and a response returned.
        '''
        return

从我上面的代码中,提交的状态转换失败并出现以下错误:

Traceback (most recent call last):
worker_1   |   File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 240, in trace_task
worker_1   |     R = retval = fun(*args, **kwargs)
worker_1   |   File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 438, in __protected_call__
worker_1   |     return self.run(*args, **kwargs)
worker_1   |   File "/app/sms_platform/apps/api/tasks.py", line 176, in run
worker_1   |     return self._send_sms(msisdn, message, request_id, correlation_id, mno, sender_id, pk=pk)
worker_1   |   File "/app/sms_platform/apps/api/tasks.py", line 126, in _send_sms
worker_1   |     sms_obj.submitted()
worker_1   |   File "/usr/local/lib/python2.7/dist-packages/django_fsm/__init__.py", line 512, in _change_state
worker_1   |     return fsm_meta.field.change_state(instance, func, *args, **kwargs)
worker_1   |   File "/usr/local/lib/python2.7/dist-packages/django_fsm/__init__.py", line 304, in change_state
worker_1   |     object=instance, method=method)
worker_1   | TransitionNotAllowed: Can't switch from state 'started' using method 'submitted'

唯一的区别是在转换源中提交的内容不像其他源那样被引用。否则,如果我引用“已提交”,它就可以正常工作。

对此感到困惑,因为所有状态都是在类的开头定义的。

最佳答案

您将started变量重新定义为方法名称的问题

class SmsMessage(models.Model)
    ... started, ...= ... "started", ...

    @transition(field=state, source='received', target=started)
    def started(self):  # <- LOL
        ....

   @transition(field=state, source=started, target=submitted)   
   def submitted(self):
        ....

>>> print(SmsMessage.started)
<unbound method SmsMessage.started>

关于python - Django FSM 状态转换错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33518370/

相关文章:

python - 导入 numpy 而不安装

python - Django 类型错误 : 'ModelBase' object is not iterable

python - 如何使 Django 的 DateTimeField 可选?

c# - 使用 "yield"关键字实现状态机

c - 分配给结构的非 const 成员时出现 "assignment of read-only member"错误

c++ - 用于 C++ 游戏的通用 FSM?

python - networkx 中的定向加权平衡树导入和最短路径

新终端窗口中的 Python sudo 无需传递密码

python - TensorFlow 不更新权重

python - Django 休息框架。检索的工作原理