25

RadioSelectウィジェットを持つChoiceFieldを含むモデルがある場合、テンプレートでラジオボタンを個別にレンダリングするにはどうすればよいですか?

会社の新入社員がデスクトップに必要なコンピューターの種類を選択できるWebアプリを構築しているとしましょう。これは関連するモデルです:

class ComputerOrder(forms.Form):
    name = forms.CharField(max_length=50)
    office_address = forms.Charfield(max_length=75)
    pc_type = forms.ChoiceField(widget=RadioSelect(), choices=[(1, 'Mac'), (2, 'PC')])

テンプレートで、Macの選択ボタンだけをレンダリングするにはどうすればよいですか?これを行うと、すべての選択肢が表示されます。

{{ form.pc_type  }}

やや素朴にこれを試しましたが、出力が生成されませんでした。

{{ form.pc_type.0 }}

(私はここSOでいくつかの同様の質問を見つけました:

Djangoフォームで、ラジオボタンをレンダリングして、ページ上で選択肢が分かれるようにするにはどうすればよいですか?
Djangoフォーム:Djangoフォームのフィールドの選択肢を反復処理する方法

しかし、私は彼らが良い答えを持っているとは感じませんでした。古い質問を復活させる方法はありますか?)

4

4 に答える 4

51

Django 1.4+では、の行とともに、の選択肢を繰り返すことができます。RadioSelect

{% for choice in form.pc_type %}
  {{ choice.choice_label }}
  <span class="radio">{{ choice.tag }}</span>
{% endfor %}

この変更により、説明した構文()を使用できるかどうかはわかりません。使用できない場合は、上記のループと。のようなタグを使用{{ form.pc_type.0 }}してこの制限を回避できます。for{% if forloop.counter0 == 0 %}

Django <1.4に縛られている場合はrender()、提案されているようにメソッドをオーバーライドするか、テンプレートにフォームフィールドを自分で作成するという少し冗長ですがそれほど複雑ではないオプションを使用できます。

 {% for choice in form.pc_type.field.choices %}
   <input name='{{ form.pc_type.name }}' 
     id='{{ form.pc_type.auto_id }}_{{ forloop.counter0 }}' type='radio' value='{{ choice.0 }}'
     {% if not form.is_bound %}{% ifequal form.pc_type.field.initial choice.0 %} checked='checked' {% endifequal %}
   {% else %}{% ifequal form.pc_type.data choice.0 %} checked='checked' {% endifequal %}{% endif %}/>
   <label for='{{ form.pc_type.auto_id }}_{{ forloop.counter0 }}'>{{ choice.1 }}</label>
 {% endfor %}

choice.0およびは、 2タプルchoice.1の最初と2番目の項目です)choices

于 2012-07-09T17:18:29.740 に答える
6

個々の無線入力のレンダリングは、RadioSelectウィジェットのrenderメソッドによって処理されます。別のレンダリングが必要な場合は、サブクラスを作成し、それに応じRadioSelectてメソッドを変更してからrender、サブクラスをフィールドのウィジェットとして使用します。

于 2012-04-19T21:42:22.963 に答える
4

選択フィールドのforループ内で利用できるものを見るだけで、知っておくべきことがわかると思います。たとえば、オプションのスパンを囲むクラスを設定するための値が必要でした(色など)。

<div>
    {% for radio_input in form.role %}
        {# Skip the empty value #}
        {% if radio_input.choice_value %}
            <span class="user-level {{ radio_input.choice_value }}">{{ radio_input }}</span>
        {% endif %}
    {% endfor %}
</div>

ご覧のとおり、序数を使用する必要がないいくつかの属性があります。

テンプレート内のPyCharmデバッグ

于 2013-04-12T22:19:37.343 に答える
2

Django 2.0以降ではforms.RadioSelect、ラジオフィールドをレンダリングするためのテンプレートをサブクラス化して「簡単に」指定できます。

class SlimRadioSelect(forms.RadioSelect):
    template_name = 'includes/slim_radio.html'

ここには、デフォルトのRadioSelectウィジェットによって結合および使用されるslim_radio.html改訂バージョンが含まれています。template_nameoption_template_name

デフォルトのRadioSelectウィジェットテンプレートは低レベルのレンダリングであり、高度に階層化されたテンプレートで構成されていることに注意してください。インクルード、条件付き、ループロジックタグがたくさんあります。

必要なものを手に入れるために掘り下げているときに、到着したことがわかりますpackages/django/forms/templates/django/forms/widgets/input.html

デフォルトウィジェットのテンプレートをオーバーライドするもう1つの奇妙な点は、 TemplatesSettingレンダラーを呼び出す必要があることです。そうしないと、サブクラスはプロジェクトの通常アクセス可能なテンプレートパスで見つけることができません。 slim_radio.html

RadioSelectのローカルのみのテンプレートパスルックアップをオーバーライドするには:

  1. あなたに追加'django.forms'しますINSTALLED_APPS;

  2. FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'あなたに追加settings.py.

これはすべて、本来あるべきよりも難しいように思われますが、それはフレームワークです。幸運を。

于 2020-04-04T18:38:42.637 に答える