Django: 在模块中实现“状态”字段的最佳方式

42 投票
7 回答
32608 浏览
提问于 2025-04-15 18:30

我在我的模块里有一个字段,用来保存对象的状态。

到目前为止,我用的是:

ORDER_STATUS = ((0, 'Started'), (1, 'Done'), (2, 'Error'))
status = models.SmallIntegerField(choices=ORDER_STATUS)

从一种状态转换到另一种状态其实很简单:

def status_str(self): return ORDER_STATUS[self.status][1]

但问题出在更新的时候。我发现自己写的代码像这样:

order.status = 2 # Error Status

这实在是太糟糕了,而且很难保持同步。我想解决这个问题的方法可能类似于C语言里的枚举(enum{})。或者,也许还有其他完全不同的解决办法?

谢谢

7 个回答

8

这个回答来得有点晚,不过为了完整性,我得提一下,django-model-utils 这个库里已经有一个叫做 StatusField 的功能,甚至还有一个更好的 StatusModel。我在需要状态的地方都在用它。

11

我通常在这种情况下会这样做:

在models.py文件中:

from static import ORDER_STATUS    
status = models.PositiveSmallIntegerField(choices=ORDER_STATUS)

在static.py文件中:

ORDER_STATUS = ((0, 'Started'), (1, 'Done'), (2, 'Error'))
ORDER_STATUS_DICT = dict((v, k) for k, v in ORDER_STATUS)

现在你可以这样做:

from static import ORDER_STATUS_DICT
order.status = ORDER_STATUS_DICT['Error']
49

也许这个问题能帮到你:通过选择名称设置Django的IntegerField
我引用一下被接受的答案(稍微调整了一下;):
把这个放到你的类里面(STATUS_CHOICES将是传给字段的choices选项的列表):

PENDING = 0
DONE = 1
STATUS_CHOICES = (
    (PENDING, 'Pending'),
    (DONE, 'Done'),
)

然后你可以这样做:order.status = Order.DONE


注意,你不需要自己实现一个方法来获取(可读的)值,Django 自己提供了get_status_display这个方法

撰写回答