在 Django 1.7 中是否不再可以使用数字键选择?

Are numerically keyed choices no longer possible in Django 1.7?

我试图将其实现为模型的选择变量:

>>> choices = (
...         (1, 'Primary'), (2, 'Secondary'), (3, 'Tertiary')
...         )

但是由于这个准神秘错误而失败:

characters.CharacterArcanumLink.priority: (fields.E005) 'choices' must
be an iterable containing (actual value, human readable name) tuples.

让我们看看,

  1. choices 是可迭代的?检查。
  2. 包含(实际值,人类可读的名称)元组?检查:实际值为整数,'human readable name'为字符串。

看起来不错。

深入 code,似乎对 Django 1.7 进行了新检查:

def _check_choices(self):
        if self.choices:
            if (isinstance(self.choices, six.string_types) or
                    not is_iterable(self.choices)):
                return [
                    checks.Error(
                        "'choices' must be an iterable (e.g., a list or tuple).",
                        hint=None,
                        obj=self,
                        id='fields.E004',
                    )
                ]
            elif any(isinstance(choice, six.string_types) or
                     not is_iterable(choice) or len(choice) != 2
                     for choice in self.choices):
                return [
                    checks.Error(
                        ("'choices' must be an iterable containing "
                         "(actual value, human readable name) tuples."),
                        hint=None,
                        obj=self,
                        id='fields.E005',
                    )
                ]
            else:
                return []
        else:
            return []

这是第二次检查,在看起来可疑的 elif 之后。让我们在上面的 choices 元组上尝试 isinstance

>>> any(isinstance(choice, six.string_types) for choice in choices)
False

不好!稍微修改一下怎么样?

>>> any(isinstance(choice[1], six.string_types) for choice in choices)
True
>>>

优秀。

我的问题是,我错过了什么吗?我是 sure 这曾经是可能的。为什么不再可能了?我是不是执行错了?

我还在 code.djangoproject 上开了一个 ticket,如果有帮助?


触发它的代码分为两部分:

class Trait(models.Model):
    PRIORITY_CHOICES = (
        (None, '')
        )
    MIN = 0
    MAX = 5
    current_value = IntegerRangeField(min_value=MIN, max_value=MAX)
    maximum_value = IntegerRangeField(min_value=MIN, max_value=MAX)
    priority = models.PositiveSmallIntegerField(choices=PRIORITY_CHOICES, default=None)
    class Meta:
        abstract = True

并且:

class CharacterSkillLink(CharacterLink, SkillLink, Trait):
    PRIORITY_CHOICES = (
        (1, 'Primary'), (2, 'Secondary'), (3, 'Tertiary')
        )
    speciality = models.CharField(max_length=200)

问题是当您只有一个选择时 - 外括号不构建元组,只是提供分组。元组的创建是由逗号提供的,而不是括号。

((None, '')) == (None, '')

你应该留下一个尾随逗号来表示你想要一个单项元组(或使用列表):

PRIORITY_CHOICES = ((None, ''), )