2013-01-13 2 views
1

Я генерирую ModelForms и хочу получить подробный контроль над тем, как они выводятся в моем шаблоне. В частности, мне нужно добавить некоторую разметку в конец каждого переключателя в каждом из моих списков выбора.Пытаться получить доступ к модели модели ModelForm Выбор выбора в шаблоне Django

Код:

# order-form.html 

{% load catname %} 
<form id = "order-form"> 
{% for form in forms %} 
<div id="gun-{{ forloop.counter }}"> 
    {% for field in form.fields %} 
     <div id="{{ field }}-item" class="item"> 
      <h3>{{ field|catname }}</h3> 
      {% for choice in form.field.choices %} {# <-- Help me out here #} 
       {{ choice.id }} 
       {{ choice.title }} 
      {% endfor %} 
     </div> 
    {% endfor %} 
{% endfor %} 
<button type="submit" id="standard-gun-form-submit">Continue to next step</button> 
</form> 

# views.py 
def get_form(request): 
    if request.method == 'POST': 
     if request.POST['gun_type'] == 'standard': 
      forms = [StandardGunForm(prefix=p) for p in range(0,2)] 
      return render_to_response('main/order-form.html', {'forms' : forms,}, RequestContext(request)) 

# forms.py 

class StandardGunForm(ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(StandardGunForm, self).__init__(*args, **kwargs) 
     for field in self.fields: 
      if isinstance(self.fields[field], ModelChoiceField): 
       self.fields[field].empty_label = None 

    class Meta: 
     model = BaseGun 
     widgets = { 
      'FrameTuning' : RadioSelect(), 
      'FrameConnection' : RadioSelect(), 
     } 
     exclude = ('price') 

Endgame: разметка, которая выглядит как этот

<form id="foo"> 
<div class="category"> 
    <div class="item"> 
     <input type="radio" name="srsbzns" value="1">Option 1</input> 
     <img src="http://placekitten.com/150/150"> 
     <p>Other foo here</p> 
    </div> 
    <div class="item"> 
     <input type="radio" name="srsbzns" value="2">Option 2</input> 
     <img src="http://placekitten.com/150/150"> 
     <p>Other foo here</p> 
    </div> 
    <div class="item"> 
     <input type="radio" name="srsbzns" value="3">Option 3</input> 
     <img src="http://placekitten.com/150/150"> 
     <p>Other foo here</p> 
    </div> 
</div> 
</form> 

из оболочки, это возвращает то, что я хочу

>>> forms = [StandardGunForm(prefix=p) for p in range(0,2)]\ 
>>> forms[0].fields['frame_tuning'].choices.queryset 

Я удивлен, что это доказывает так сложно!

Бонус: У меня есть панель DEBUG = True и Django Debug. Можно ли сбросить переменные в браузер, чтобы я мог видеть, как выглядит этот материал, когда я разворачиваюсь?

Спасибо!

+1

Я думаю, '{% для id, title in field.choices%}', но почему бы не просто '{{field}}' с помощью специального виджета?Если вам нужен пользовательский вывод, напишите собственный виджет ... :-) –

+0

Да, пользовательский виджет может быть способом – starsinmypockets

ответ

0
{% for choice in form.field.choices %} {# <-- Help me out here #} 
      {{ choice.id }} 
      {{ choice.title }} 
{% endfor %} 

Посмотрите, что вы здесь делаете, вы в буквальном смысле пытается получить доступ к полю под названием «поле» каждый раз, когда в этом цикле, который предположительно не существует.

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

{% for field in form.fields %} 
    {% for choice in field.choices %} 
+0

Увы, это тоже не сработает. Я пробовал много комбинаций перед публикацией здесь. Я предполагаю, что я просто напишу собственный виджет и создаю свою разметку. – starsinmypockets

+2

starsinmypockets, попробуйте field.field.choices –

4

Мне нужно было сделать что-то подобное и начать с этого пути. Я хотел создать строки таблицы из ModelChoiceField, где каждый столбец имел другое поле экземпляра модели (а затем я разрешил бы фильтровать строки таблицы через JavaScript).

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

<form action="{% url 'some_view' %}" method="post"> 
    {% csrf_token %} 
    {% if form.non_field_errors %} 
     {{ form.non_field_errors }} 
    {% endif %} 

    {% for field in form %} 
     {{ field.label }} 

     {% if field.field.choices %} 
      {% for model_instance in field.field.choices.queryset %} 
      {{ model_instance.id }} 
      {% endfor %} 
     {% else %} 
      {{ field }} 
     {% endif %} 

     {% if field.errors %} 
      {{ field.errors|striptags }} 
     {% endif %} 

    {% endfor %} 

    <button type="submit">Submit</button> 
</form> 

Однако, на данный момент мы разобрали блестящий виджет (в моем случае CheckboxSelectMultiple) и должны повторно собрать входной HTML формы, используя код шаблона. Я не нашел прямого способа одновременной итерации над ModelChoiceField для доступа к полям экземпляра модели и получения тегов формы HTML для выбора.

Возможно, есть способ, но я отказался от своей попытки и создал свою собственную форму HTML, обрабатывая все данные POST в представлении. Это оказалось намного проще. ModelForms действительно приятны и удобны, но использование их для чего-то, за что они не были построены, может оказаться сложнее.

Я решил, что опубликую это на случай, если кто-то попытается это сделать по другой причине. Надеюсь, поможет.

0

Очень поздно, но я читаю сейчас, и это то, что он работал для меня

{% for field in form %} 
 
    {% for x, y in field.field.choices %} 
 
    {{x}} 
 
    {{y}} 
 
    {% endfor %} 
 
{% endfor %}

Где «х» идентификатор или код, и «у» является читаемое значение или название.

Смежные вопросы