How do I iterate over the options of a SelectField in a template?

前端 未结 5 876
长情又很酷
长情又很酷 2020-12-23 20:47

I have a select field in the form and now I need to iterate over options in this field.

{{ form.myselect }} gives me this:


                        
    
提交评论

  • 2020-12-23 21:16

    With radio buttons in your template use.

        <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>
    
    0 讨论(0)
  • 2020-12-23 21:21

    I've been struggling with this problem today and found the solution. Yes, you can iterate over options of the select tag directly in template. Here's how to do it in template:

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

    In this case I have a customer field in the form which has choices set up as follows:

    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()]
    

    Hope this helps

    0 讨论(0)
  • 2020-12-23 21:27

    Got it to work with:

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

    BUT REALLY, a better way to do this is with django-widget-tweaks:

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

    Doing it with django-widget-tweaks will also set the default 'selected="selected"' for you, which is super nice!

    0 讨论(0)
  • 2020-12-23 21:28

    This is a cleaner solution, you can set the attributes using a custom Widget. This way you don't have to render the field manually:

    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 讨论(0)
  • 提交回复
    热议问题