在 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.
让我们看看,
- choices 是可迭代的?检查。
- 包含(实际值,人类可读的名称)元组?检查:实际值为整数,'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, ''), )
我试图将其实现为模型的选择变量:
>>> choices = (
... (1, 'Primary'), (2, 'Secondary'), (3, 'Tertiary')
... )
但是由于这个准神秘错误而失败:
characters.CharacterArcanumLink.priority: (fields.E005) 'choices' must
be an iterable containing (actual value, human readable name) tuples.
让我们看看,
- choices 是可迭代的?检查。
- 包含(实际值,人类可读的名称)元组?检查:实际值为整数,'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, ''), )