2

我正在生成 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>

从外壳,这返回我想要的

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

我很惊讶这证明如此具有挑战性!

奖励:我启用了 DEBUG = True 和 Django Debug 工具栏。是否可以将变量转储到浏览器,这样我可以在深入研究时看到这些东西的样子?

谢谢!

4

4 回答 4

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

我想我会发布这个,以防有人出于其他原因试图这样做。希望能帮助到你。

于 2013-07-11T21:27:19.760 回答
1

很晚了,但我现在正在阅读,这对我有用

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

其中“x”是 id 或代码,“y”是可读值或标题。

于 2017-08-22T16:02:03.470 回答
1

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

{% for choice, label in form.field_name.field.choices %}
    {{ choice.value }}
    {{ choice.instance }} 
    {{ choice.instance.instance_attribute }}
    {{ label }}
{% endfor %}
于 2021-05-25T15:08:49.410 回答
0
{% for choice in form.field.choices %} {# <-- Help me out here #}
            {{ choice.id }}
            {{ choice.title }}
{% endfor %}

看看你在这里做什么,你实际上是在每次在这个循环中尝试访问一个名为“field”的字段,这可能不存在。

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

{% for field in form.fields %}
   {% for choice in field.choices %}
于 2013-01-13T22:45:59.797 回答