当使用Django的ModelChoiceField
时,如果需要= False,则会自动生成额外选项('', '--------')
。选择此选项后,它会在None
中以cleaned_data
结尾。在使用常规ChoiceField
时,我如何(惯用)重现此行为?
我注意到的一些事情:
('', '---------')
自动添加到choices
列表中,因此似乎需要手动添加它。我觉得应该有办法通过不同地设置其中一个参数来将它添加到选项中,所以如果存在,我很乐意听到它。''
到None
的转换仍必须在使用cleaned_data
的代码中手动完成。这意味着处理ModelChoiceField
的代码必须与ChoiceField
代码略有不同,这可能会导致细微的错误。再说一次:如果有人知道更好的习语,我很乐意听到。TypedChoiceField
对''
进行了一些神奇的处理。特别是,它没有像人们期望的那样将它提供给coerce
函数。请考虑以下代码:
def int_or_none(s):
if s.isnumeric():
return int(s)
return None
class NoneForm(forms.Form):
field = forms.TypedChoiceField(
choices=[('', '--------'), ('1', 'One'), ('2', 'Two')],
required=False, coerce=int_or_none)
def home(request):
if request.method == "POST":
form = NoneForm(request.POST)
if form.is_valid():
assert type(form.cleaned_data['field']) in [int, type(None)]
print form.cleaned_data['field']
form = NoneForm()
return HttpResponse(
"""<form method="POST">""" +
form.as_table() +
"""<input type="submit"></form>""")
上面的断言失败了!
让Django的各种版本的ChoiceField
以惯用的方式清理到None
真的很难吗?
答案 0 :(得分:1)
这是基于rantanplan's comment关于empty_value
参数的结果。
特别注意,空值的选择在选项中实现为''
(就像在ModelChoiceField
中一样,所以这很好)。
class NoneForm(forms.Form):
field = forms.TypedChoiceField(
choices=[('', '--------'), ('1', 'One'), ('2', 'Two')],
required=False, coerce=int, empty_value=None)
def home(request):
if request.method == "POST":
form = NoneForm(request.POST)
if form.is_valid():
assert type(form.cleaned_data['field']) in [int, type(None)]
print form.cleaned_data['field']
form = NoneForm()
return HttpResponse(
"""<form method="POST">""" +
form.as_table() +
"""<input type="submit"></form>""")
现在断言成功了。