我正在生成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工具栏。是否可以将变量转储到浏览器中,因此我可以看到这些内容在我向下钻取时的样子?
谢谢!
答案 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)
很晚,但我现在正在阅读,这就是它对我有用的作用
{% for field in form %}
{% for x, y in field.field.choices %}
{{x}}
{{y}}
{% endfor %}
{% endfor %}
&#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 %}