J'ai un champ de sélection dans le formulaire et je dois maintenant parcourir les options de ce champ.
{{ form.myselect }}
me donne ceci:
<select name="myselect" id="id_myselect">
<option value="" selected="selected">---------</option>
<option value="2">Item 1</option>
<option value="3">Item 2</option>
...
</select>
Maintenant, je dois ajouter des attributs aux options et à cause de cela, j'ai besoin de:
<select name="myselect" id="id_myselect">
{% for x in form.myselect %}
<option value="{{ x.id }}">{{ x.name }}</option>
{% endfor %}
</select>
mais il y a une erreur:
Caught TypeError while rendering: 'BoundField' object is not iterable
J'essayais form.myselect.all
, form.myselect.option_set
mais ça ne donne rien
J'ai eu du mal avec ce problème aujourd'hui et j'ai trouvé la solution. Oui, vous pouvez parcourir les options de la balise select directement dans le modèle. Voici comment le faire dans le modèle:
<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>
Dans ce cas, j'ai un champ Client dans le formulaire qui a des choix configurés comme suit:
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()]
J'espère que cela t'aides
Je l'ai fait fonctionner avec:
<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>
MAIS VRAIMENT, une meilleure façon de le faire est avec Django-widget-tweaks :
{% load widget_tweaks %}
{{ form.myselect|add_class:"i-can-haz-custom-classes-easily" }}
Le faire avec Django-widget-tweaks définira également la valeur par défaut 'selected = "selected"' pour vous, ce qui est super sympa!
Je fais de cette façon:
<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>
Il s'agit d'une solution plus propre, vous pouvez définir les attributs à l'aide d'un widget personnalisé. De cette façon, vous n'avez pas à rendre le champ manuellement:
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
)
Avec des boutons radio dans votre modèle, utilisez.
<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>