Как перебрать опции SelectField в шаблоне? - PullRequest
27 голосов
/ 10 февраля 2012

У меня есть поле выбора в форме, и теперь мне нужно перебрать опции в этом поле.

{{ form.myselect }} дает мне это:

<select name="myselect" id="id_myselect">
    <option value="" selected="selected">---------</option>
    <option value="2">Item 1</option>
    <option value="3">Item 2</option>
    ...
</select>

Теперь мне нужно добавитьнекоторые атрибуты опций и из-за этого мне нужно:

<select name="myselect" id="id_myselect">
{% for x in form.myselect %}
    <option value="{{ x.id }}">{{ x.name }}</option>
{% endfor %}
</select>

, но есть ошибка:

Caught TypeError while rendering: 'BoundField' object is not iterable

Я пытался form.myselect.all, form.myselect.option_set, но этоничего не дает

Ответы [ 5 ]

70 голосов
/ 23 мая 2012

Я боролся с этой проблемой сегодня и нашел решение. Да, вы можете перебирать опции тега select прямо в шаблоне. Вот как это сделать в шаблоне:

<select id="id_Customer" name="Customer">
{% for x,y in form.fields.Customer.choices %}
    <option value="{{ x }}"{% if form.fields.Customer.value == x %} selected{% endif %}>{{ y }}</option>
{% endfor %}
</select>

В этом случае у меня есть поле «Клиент» в форме, варианты выбора которого настроены следующим образом:

class Some_Form(forms.Form):
    Customer = forms.ChoiceField(label=u'Customer')

    def __init__(self, *args, **kwargs):
        super(Some_Form, self).__init__(*args, **kwargs)
        self.fields['Customer'].choices = [(e.id, e.Customer) for e in Customers.objects.all()]

Надеюсь, это поможет

23 голосов
/ 20 апреля 2013

Получил работать с:

    <select name="myselect" class="i-can-add-my-own-attrs-now" id="id_myselect">
        {% for id, name in form.myselect.field.choices %}
        <option value="{{ id }}">{{ name }}</option>
        {% endfor %}
    </select>

НО ДЕЙСТВИТЕЛЬНО, лучший способ сделать это с помощью django-widget-tweaks :

    {% load widget_tweaks %}
    {{ form.myselect|add_class:"i-can-haz-custom-classes-easily" }}

Выполнение этого с django-widget-tweaks также установит для вас значение по умолчанию 'selected = "selected"', что очень приятно!

7 голосов
/ 13 апреля 2015

Я делаю так:

<select id="id_construction_type" name="construction_type" class="form-control input-md">
{% for value, key in form_urban.fields.construction_type.choices %}
    <option value="{{ value }}"{% if form_urban.initial.construction_type == value %} selected {% endif %}>
        {{ key }}
    </option>
{% endfor %}
</select>
2 голосов
/ 12 марта 2019

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

class CustomSelectWidget(forms.Select):
    def create_option(self, name, value, *args, **kwargs):
        option = super().create_option(name, value, *args, **kwargs)
        if value:
            instance = self.choices.queryset.get(pk=value)  # get instance
            option['attrs']['custom_attr'] = instance.field_name  # set option attribute
        return option

class SomeForm(forms.ModelForm):
    some_field = forms.ModelChoiceField(
        queryset=SomeModel.objects.all(),
        widget=CustomSelectWidget
    )
0 голосов
/ 29 мая 2014

С радио-кнопками в вашем шаблоне.

    <table>
        {% for x,y in form.fields.Customer.choices %}
        <tr>
            <td><input id="id_Customer_{{x}}" {% if form.fields.Customer.value == x %}checked="checked"{% endif %} name="Customer" type="radio" value="{{x}}" /></td>
            <td>{{ y }}</td>
        </tr>
        {% endfor %}
    </table>
...