如果需要,可以在表单中添加字段django

时间:2017-05-26 07:39:09

标签: django django-forms

我正在尝试制作一个可以选择一次添加多个对象的表单。我希望它有一个按钮"添加另一个" - 单击时,将显示一个新的表单字段以添加其他对象。如果之前没有提交输入,我希望表单保留它。是否可以使用模板标签(即django模板标签而不是javascript)?

1 个答案:

答案 0 :(得分:1)

您的表单必须根据从POST传递给它的一些变量构建(或盲目检查属性)。每次重新加载视图时都会构造表单本身,错误与否,因此HTML需要包含有关构建正确数量的字段以进行验证的字段数的信息。

我会以FormSet的工作方式来看待这个问题:有一个隐藏字段,其中包含活动表单的数量,每个表单名称都以表单索引为前缀。实际上,您可以创建一个字段FormSet

https://docs.djangoproject.com/en/dev/topics/forms/formsets/#formsets

这是一个从头开始的 - 它应该给你一些想法。它还回答了有关将参数传递给__init__的问题 - 您只需将参数传递给对象构造函数:MyForm('arg1', 'arg2', kwarg1='keyword arg')

### Views

类MyForm(forms.Form):     original_field = forms.CharField()     extra_field_count = forms.CharField(widget = forms.HiddenInput())

def __init__(self, *args, **kwargs):
    extra_fields = kwargs.pop('extra', 0)

    super(MyForm, self).__init__(*args, **kwargs)
    self.fields['extra_field_count'].initial = extra_fields

    for index in range(int(extra_fields)):
        # generate extra fields in the number specified via extra_fields
        self.fields['extra_field_{index}'.format(index=index)] = \
            forms.CharField()

def myview(request):     如果request.method =='POST':         form = MyForm(request.POST,extra = request.POST.get('extra_field_count')         如果form.is_valid():             打印“有效!”     其他:         form = MyForm()     return render(request,“template”,{'form':form})

### HTML

form_count = Number($("[name=extra_field_count]").val());
// get extra form count so we know what index to use for the next item.
$("#add-another").click(function() {
    form_count ++;

    element = $('<input type="text"/>');
    element.attr('name', 'extra_field_' + form_count);
    $("#forms").append(element);
    // build element and append it to our forms container

    $("[name=extra_field_count]").val(form_count);
    // increment form count so our view knows to populate 
    // that many fields for validation
})

<form>
<div id="forms">
    {{ form.as_p }}
</div>
<button id="add-another">add another</button>
<input type="submit" />
</form>