创建具有动态字段数量的Django表单类
我正在做一个类似在线商店的项目。我想制作一个表单,让顾客可以购买商品,并选择她想买多少件。不过,每件商品在购买时都需要选择颜色。所以,表单中的字段数量是不固定的:如果顾客买了3件商品,她就应该看到3个选择颜色的下拉框;如果她买了7件商品,那就应该有7个这样的下拉框。
我打算用JavaScript来控制这些HTML表单字段的显示和隐藏。但是,我该如何在我的Django表单类中处理这个问题呢?我发现表单字段是类的属性,所以我不太清楚如何处理某些表单实例需要3个颜色字段,而有些需要7个的问题。
有没有什么建议呢?
5 个回答
22
你可以这样做:
def __init__(self, n, *args, **kwargs):
super(your_form, self).__init__(*args, **kwargs)
for i in range(0, n):
self.fields["field_name %d" % i] = forms.CharField()
然后当你创建表单实例时,你只需要这样做:
forms = your_form(n)
这只是一个基本的想法,你可以根据自己的需要修改代码。:D
39
这里还有一个选择:你考虑过使用表单集吗?因为你的字段都是一样的,表单集正好就是用来处理这种情况的。
Django的管理后台使用FormSet
加上一点JavaScript来添加任意长度的内嵌表单。
class ColorForm(forms.Form):
color = forms.ChoiceField(choices=(('blue', 'Blue'), ('red', 'Red')))
ColorFormSet = formset_factory(ColorForm, extra=0)
# we'll dynamically create the elements, no need for any forms
def myview(request):
if request.method == "POST":
formset = ColorFormSet(request.POST)
for form in formset.forms:
print "You've picked {0}".format(form.cleaned_data['color'])
else:
formset = ColorFormSet()
return render(request, 'template', {'formset': formset}))
JavaScript
<script>
$(function() {
// this is on click event just to demo.
// You would probably run this at page load or quantity change.
$("#generate_forms").click(function() {
// update total form count
quantity = $("[name=quantity]").val();
$("[name=form-TOTAL_FORMS]").val(quantity);
// copy the template and replace prefixes with the correct index
for (i=0;i<quantity;i++) {
// Note: Must use global replace here
html = $("#form_template").clone().html().replace(/__prefix_/g', i);
$("#forms").append(html);
};
})
})
</script>
模板
<form method="post">
{{ formset.management_form }}
<div style="display:none;" id="form_template">
{{ formset.empty_form.as_p }}
</div><!-- stores empty form for javascript -->
<div id="forms"></div><!-- where the generated forms go -->
</form>
<input type="text" name="quantity" value="6" />
<input type="submit" id="generate_forms" value="Generate Forms" />
76
Jacob Kaplan-Moss 写了一篇关于动态表单字段的详细文章:http://jacobian.org/writing/dynamic-form-generation/
简单来说,就是在创建表单的时候,你可以往表单的 self.fields
字典里添加更多的项目。