Как отображать отдельные кнопки переключателя в Django? - программирование
Подтвердить что ты не робот

Как отображать отдельные кнопки переключателя в Django?

Если у меня есть модель, содержащая ChoiceField с виджетами RadioSelect, как я могу отображать переключатели отдельно в шаблоне?

Скажем, я создаю веб-приложение, которое позволяет новым сотрудникам компании выбирать, какой компьютер они хотят на своем рабочем столе. Это соответствующая модель:

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 Forms: как перебирать выбор поля в форме Django

Но я не чувствовал, что у них хорошие ответы. Есть ли способ воскресить старые вопросы?)

4b9b3361

Ответ 1

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 и choice.1 - это первый и второй элементы в choices двухкортеже)

Ответ 2

Обработка отдельных радиовходов осуществляется с помощью метода RadioSelect widget render. Если вы хотите другой рендеринг, подкласс RadioSelect, соответствующим образом измените метод render, а затем используйте свой подкласс в качестве виджета поля.

Ответ 3

Я думаю, что просто глядя на то, что доступно внутри цикла 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 Debugging Inside a Template