1

を使用する場合ModelChoiceField、required = Falseを指定すると、追加の選択肢('', '--------')が自動的に生成されます。このオプションを選択すると、Noneのようになりcleaned_dataます。通常の使用時にこの動作を(慣用的に)再現するにはどうすればよいChoiceFieldですか?

私が注意したいくつかのこと:

  • ('', '---------')タプルをのリストに自動的に追加する方法が見つからなかったchoicesため、手動で追加する必要があるようです。パラメータの1つを別の方法で設定することで、選択肢に追加する方法があるはずだと思います。そのため、それが存在する場合は、ぜひ聞いてみたいと思います。
  • ''からへの変換はNone、を使用するコードで手動で行う必要がありますcleaned_data。これは、ModelChoiceFieldsを処理するコードがコードと微妙に異なる必要があることを意味し、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

4

1 に答える 1

1

これは、パラメーターに関する rantanplan のコメントに基づいた結果です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>""")

これでアサーションは成功します。

于 2012-11-09T14:03:13.723 に答える