Итерации по выбору в CheckboxSelectMultiple

У меня есть поле CheckboxSelectMultiple, почему я не могу перебирать отдельные варианты?

Это не работает:

  {%for choice in form.travels.choices%}
    {{choice}}
  {%endfor%}

Даже указание {{choice.0}} не помогает, как я могу это сделать?

Спасибо

Ответ 1

Внутри шаблона поле travels является фактически экземпляром BoundField (который является объектом Django, который связывает поле и его значение для рендеринга). Это означает, что свойства несколько отличаются.

Повторить выбор в виде кортежа:

{% for choice in form.travels.field.choices %}
    {{ choice }} - 
{% endfor %}

Produces: (1, 'One') - (2, 'Two') -

Для повторного итерации элементов в наборах по выбору отдельно:

{% for choice_id, choice_label in form.travels.field.choices %}
    {{ choice_id }} = {{ choice_label }} <br/>
{% endfor %}

Produces: 1 = One
          2 = Two

Надеюсь, что это поможет. Тем не менее, я не уверен в контексте, в котором вам нужно это делать; на поверхности, это не кажется очень джангоподобным. Вы можете обнаружить, что использование настраиваемого поля формы или настраиваемого тега шаблона дает вам более переносимую, повторно используемую реализацию, которая лучше поддерживает django, предназначенное для разделения между кодом представления и кодом шаблона. Конечно, YMMV, и вполне возможно, что подход прямой итерации подходит вам в этом случае.

Ответ 2

если у вас есть Form.ModelForm с полем выбора, вы можете его перенести в шаблон простым фильтром шаблонов.

forms.py

    STATE_CHOICES = (
    (10, 'NO'),
    (4, 'YES'),
    (18, 'Send to another Chemist for Review'),
    (34, 'Send to another Market Expert for Review'),
    (20, 'HOLD'),
)
new_state = forms.ChoiceField(
    choices=STATE_CHOICES,
    required=True,
)

Шаблон:

{{ business_manager_form.new_state|filter_project_states:project }}

и вот фильтр сам.

@register.filter()
def filter_project_states(argv, project):
if project.department.id != 4:
argv.field.choices = [choice for choice in argv.field.choices if choice[0] != 34]
return argv

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