Тег шаблона Django для получения определенного поля формы

#django #django-templates

#django #django-шаблоны

Вопрос:

У меня есть приложение для опроса, которое создает формы динамического размера. Я использую формулу «question_id_part», где вопрос исправлен, id — это идентификатор задаваемого вопроса, а part — одна из трех частей.

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

 {% load my_tags %}
...
{% for category in survey.category_set.all %}
    <h3>{{category}}</h3>
    {% for question in category.factor_set.all %}
        {% get_field_for_question_part question.id form "type" %} 
    {% endfor %}
{% endfor %}
...
  

Тогда у меня есть соответствующий тег шаблона, который выглядит следующим образом:

 @register.simple_tag
def get_field_for_question_part(question_id, form, part):
    field_name = "question_%s_%s" % (question_id, part)
    field = form.fields[field_name]
    return BoundField(form, field, field_name)
  

Мой вопрос заключается в следующем:
При явном импорте BoundField мой тег шаблона слишком много знает о том, как формы работают внутри и, следовательно, уязвим для будущих изменений в непубличном поведении форм. Таким образом, мне кажется, что BoundField должно быть доступно каким-то образом как метод в field — но, хоть убейте, я не могу понять, каким будет этот метод. Я упускаю что-то очевидное?

Комментарии:

1. Немного запутанный, вы создаете поля на лету или просто пытаетесь получить доступ к существующему полю в форме?

2. просто пытаюсь получить доступ к существующим полям.

3. Хороший вопрос, я довольно долго боролся с ним, пока не попал сюда. В шаблоне мы можем просто сделать, form.field_name но это не то же самое, если мы передаем тот же form объект в тег шаблона.

Ответ №1:

Попробуйте:

 @register.simple_tag
def get_field_for_question_part(question_id, form, part):
    field_name = "question_%s_%s" % (question_id, part)
    return form.__getitem__(field_name)
  

Смотрите определение метода в строке 101 здесь: django/forms/forms.py

Комментарии:

1. это должно сработать, я не могу представить, чтобы библиотека форм когда-либо выделяла getitem . Спасибо.

2. отличный ответ. Некоторое время боролся с этим, пока не приземлился здесь. Спасибо!