试图在Django模板中访问ModelForm字段modelChoice选项

时间:2013-01-13 20:08:02

标签: django django-forms django-templates

我正在生成ModelForms,并希望对我们模板中的输出方式进行精细控制。具体来说,我需要在每个选择列表中的每个单选按钮的末尾添加一些标记。

代码:

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

从shell中返回我想要的内容

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

我很惊讶这证明非常具有挑战性!

Bonus:我启用了DEBUG = True和Django Debug工具栏。是否可以将变量转储到浏览器中,因此我可以看到这些内容在我向下钻取时的样子?

谢谢!

4 个答案:

答案 0 :(得分:4)

我必须做类似的事情并开始沿着这条路走下去。我想从ModelChoiceField创建表行,其中每列都有一个不同的模型实例字段(然后我允许通过JavaScript过滤表行)。

我在Django文档中找不到它,但是Django源码的快速浏览显示了这种方式。您可以访问查询集来访问模型实例,如下所示:

<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非常好用且方便,但是将它们用于不是为它们构建的东西最终会变得更加困难。

我想我会发布这个以防万一有人因为其他原因而试图这样做。希望它有所帮助。

答案 1 :(得分:1)

很晚,但我现在正在阅读,这就是它对我有用的作用

&#13;
&#13;
{% for field in form %}
  {% for x, y in field.field.choices %}
    {{x}}
    {{y}}
  {% endfor %}
{% endfor %}
&#13;
&#13;
&#13;

其中&#34; x&#34;是id或代码,&#34; y&#34;是可读的值或标题。

答案 2 :(得分:1)

您可以访问每个选项的底层模型实例:

{% for choice, label in form.field_name.field.choices %}
    {{ choice.value }}
    {{ choice.instance }} 
    {{ choice.instance.instance_attribute }}
    {{ label }}
{% endfor %}

答案 3 :(得分:0)

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

看看你在这里做了什么,你真的试图访问一个名为&#34; field&#34;每次都在这个循环中,这可能是不存在的。

您需要获取您正在迭代的字段对象,并访问该选项属性。

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