【问题标题】:How do I iterate over the options of a SelectField in a template?如何迭代模板中 SelectField 的选项?
【发布时间】:2012-03-02 12:32:39
【问题描述】:

我在表单中有一个选择字段,现在我需要遍历该字段中的选项。

{{ 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.allform.myselect.option_set,但没有任何效果

【问题讨论】:

  • 那么你想要的是所有&lt;option&gt; 没有&lt;select&gt; 并且没有空白(-----)选项?还是我错过了什么? ...您想在这里具体实现什么目标?
  • 不,我想为选项添加一些属性,因此需要以某种方式在 `{% for x in form.myselect %}` 循环中添加它。
  • 我的建议是更改小部件并在代码中执行:docs.djangoproject.com/en/dev/ref/forms/widgets
  • 谢谢詹姆斯。我希望有一些方法可以迭代模板中的选项。

标签: django django-forms django-templates


【解决方案1】:

我今天一直在努力解决这个问题并找到了解决方案。是的,您可以直接在模板中迭代选择标签的选项。以下是如何在模板中执行此操作:

<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>

在这种情况下,我在表单中有一个 customer 字段,其选项设置如下:

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

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

希望对你有帮助

【讨论】:

  • 我遇到了同样的问题并且成功了,没有改变其他任何东西,只是添加了:{% for c in form.fields.customer.queryset %}&lt;option value="{{ c.id }}"&gt;{{ c.name|capfirst }}&lt;/option&gt;{% endfor %}
  • 设置选择对我不起作用。而不是form.fields.Customer.value,我不得不使用form.initial.Customer
【解决方案2】:

可以使用:

    <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"',非常棒!

【讨论】:

  • 但这只会将类添加到
【解决方案3】:

我是这样做的:

<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>

【讨论】:

    【解决方案4】:

    这是一个更简洁的解决方案,您可以使用自定义 Widget 设置属性。这样您就不必手动渲染该字段:

    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
        )
    

    【讨论】:

      【解决方案5】:

      在您的模板中使用单选按钮。

          <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>
      

      【讨论】:

        猜你喜欢
        • 2022-10-14
        • 2018-01-20
        • 2021-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-04
        相关资源
        最近更新 更多