我有一个依赖于元组的Django模型.我想知道在我的Django程序中引用该元组中的常量的最佳实践是什么.例如,在这里,我想将" default=0" 指定为更具可读性且不需要评论的东西.有什么建议?
Status = (
    (-1, 'Cancelled'),
    (0, 'Requires attention'),
    (1, 'Work in progress'),
    (2, 'Complete'),
)
class Task(models.Model):
    status = models.IntegerField(choices=Status, default=0) # Status is 'Requires attention' (0) by default.
编辑:
如果可能的话,我想完全避免使用一个数字.不知何故,使用字符串'需要注意'将更具可读性.
Ala*_*air 60
定义整数值的常量非常常见,如下所示:
class Task(models.Model):
    CANCELLED = -1
    REQUIRES_ATTENTION = 0
    WORK_IN_PROGRESS = 1
    COMPLETE = 2
    Status = (
        (CANCELLED, 'Cancelled'),
        (REQUIRES_ATTENTION, 'Requires attention'),
        (WORK_IN_PROGRESS, 'Work in progress'),
        (COMPLETE, 'Complete'),
    )
    status = models.IntegerField(choices=Status, default=REQUIRES_ATTENTION)
通过移动常量和Status类内部,您可以保持模块的名称空间更清晰,作为奖励,您可以参考Tasks.COMPLETE导入Tasks模型的任何位置.
ran*_*lan 16
CANCELED, ATTENTION, WIP, COMPLETE = range(-1, 3)
Status = (
    (CANCELED, 'Cancelled'),
    (ATTENTION, 'Requires attention'),
    (WIP, 'Work in progress'),
    (COMPLETE, 'Complete'),
)
class Task(models.Model):
    status = models.IntegerField(choices=Status, default=CANCELED)
只有一个原因是您希望将它放在类命名空间之外,并且只有当这些语义由应用程序的其他模型共享时才会出现.即你无法决定他们属于哪种特定型号.
虽然在您的特定示例中似乎不是这种情况.
Lut*_*elt 12
Enum你写道:"如果可能,我想完全避免使用一个数字." 事实上,一个命名的代表显然更加pythonic.然而,裸字符串易受错别字的影响.
Python的3.4引入了一种称为模块 
 enum提供Enum与IntEnum伪类与此情况有所帮助.有了它,您的示例可以如下工作:
# in Python 3.4 or later:
import enum  
class Status(enum.IntEnum):
    Cancelled = -1,
    Requires_attention = 0,
    Work_in_progress = 1,
    Complete = 2
def choiceadapter(enumtype):
    return ((item.value, item.name.replace('_', ' ')) for item in enumtype)
class Task(models.Model):
    status = models.IntegerField(choices=choiceadapter(Status), 
                                 default=Status.Requires_attention.value)
一旦Django团队回升Enum,它
 choiceadapter甚至会被建立在Django中.
你可以使用一个namedtuple,使用一个常量似乎适合的永恒.;-)
>>> from collections import namedtuple
>>> Status = namedtuple('Status', ['CANCELLED', 'REQUIRES_ATTENTION', 'WORK_IN_PROGRESS', 'COMPLETE'])(*range(-1, 3))
>>> Status
Status(CANCELLED=-1, REQUIRES_ATTENTION=0, WORK_IN_PROGRESS=1, COMPLETE=2)
>>> Status.CANCELLED
-1
>>> Status[0]
-1
在这种情况下,Task像Alasdair的答案一样使用属性作为常量更有意义,但是命名元组是非常便宜的替代词和不会改变的对象.如果你想在内存中有很多它们,特别方便.它们就像常规元组一样,具有描述性__repr__和属性访问权.
| 归档时间: | 
 | 
| 查看次数: | 22152 次 | 
| 最近记录: |