我正在研究一些Django表单,其代码库是从其他人继承的,这很好,但却增加了混乱。
我正在尝试将第二个formset添加到表单中。添加第二个formset时,两个formset都出现在页面上,但似乎在后端不包含任何表单。以下是我的代码示例(我添加的内容可能比推荐更多,但我不想错过重要内容):
view.py:
class Thing(StaffRequiredMixin, DetailView):
model = models.Thing
def post(self, request, *args, **kwargs):
...
context = self.get_context_data(**kwargs)
dispatch = {
"thing_form": self.handle_thing_form,
...
}
return dispatch[self.request.POST.get("form_name")](context)
...
def get_context_data(self, *args, **kwargs):
context = super(Thing, self).get_context_data(*args, **kwargs)
thing = self.model.objects.get(pk=self.kwargs["pk"])
context["thing"] = thing
to_handle = self.request.POST.get("form_name")
if to_handle == "thing_form":
context["thing_form"] = forms.Thing(
self.request.POST,
instance=thing)
context["formset1"] = forms.FormSet1(
self.request.POST,
queryset=models.Model1.objects.filter(thing=self.object),
prefix="thing1")
context["formset2"] = forms.FormSet2(
self.request.POST,
queryset=models.Model2.objects.filter(thing=self.object),
prefix="thing2")
else:
context["thing_form"] = forms.Thing(
instance=thing,
user=self.request.user)
context["formset1"] = forms.FormSet1(
queryset=models.Model1.objects.filter(thing=self.object),
prefix="stuff1")
context["formset2"] = forms.FormSet2(
queryset=models.Model2.objects.filter(thing=self.object),
prefix="stuff2")
# Other to_handle stuff
...
return context
def handle_thing_form(self, context):
form = context['thing_form']
formset1 = context['formset1']
formset2 = context['formset2']
if form.is_valid() and formset1.is_valid() and formset2.is_valid():
# Do some form logic
...
form.save()
# Formset stuff:
# here, the formsets contain no forms
changed_1 = [f for f in formset1 if f.has_changed()]
changed_2 = [f for f in formset2 if f.has_changed()]
for a_form in changed_1:
#Do some formset logic
...
a_form.save()
for a_form in changed_2:
#similar to 1
return HttpResponseRedirect(self.get_next_url())
return self.render_to_response(context)
forms.py:
class Form1(ModelForm):
class Meta:
model = models.Model1
fields = ("field1", "field2", ...)
def __init__(self, *args, **kwargs):
super(Form1, self).__init__(*args, **kwargs)
# Some readonly widget stuff etc
...
class Form2(ModelForm):
#Same idea as Form1
...
FormSet1 = modelformset_factory(models.Model1, form=Form1, extra=0)
FormSet2 = modelformset_factory(models.Model2, form=Form2, extra=0)
模板:
<form id="thing-form" method="post">
<input type="hidden" name="form_name" value="thing_form" />
{% for field in thing_form.visible_fields %}
{{ field }}
...
{% endfor %}
<a id="add-form1">Add</a>
{{formset1.management_form}}
<div id="formset1-div">
{% for form in formset1.forms %}
{{form.id}}
{% for field in form.visible_fields %}
<div class="controls">
{{field}}
</div>
{% endfor %}
{% endfor %}
</div>
<div id="empty-form1>
{% for field in formset1.empty_form.visible_fields %}
<div class="controls">
{{field}}
</div>
{% endfor %}
</div>
{{formset2.management_form}}
<div id="formset2-div">
{# same idea as above #}
...
</div>
<button type="submit">Update</button>
</form>
的javascript:
$(document).ready(function(){
$('#add-form1').click(function() {
$('#formset1-div').prepend($('#empty_form1').html().replace(/__prefix__/g, 'thing1'));
$('#id_form-TOTAL_FORMS').val(parseInt('thing1') + 1);
});
if ($("#formset1-div input").length === 0){
$("#add-form1").trigger("click");
}
// Similar button stuff for formset2
...
})
无论如何,我在这里添加了很多,但我这样做是因为我不确定我哪里出错了,或者即使我想做的事情也是可能的。
答案 0 :(得分:1)
哇,我真傻。 javascript部分应该是这样的:
$(document).ready(function(){
$('#add-form1').click(function() {
var thing1_index = $('#id_thing1-TOTAL_FORMS').val();
$('#formset1-div').prepend($('#empty_form1').html().replace(/__prefix__/g, thing1_index));
$('#id_thing1-TOTAL_FORMS').val(parseInt(thing1_index) + 1);
});
if ($("#formset1-div input").length === 0){
$("#add-form1").trigger("click");
}
// Similar button stuff for formset2
...
})
不确定我是如何错过显而易见的parseInt('thing1')
毫无意义的。
无论如何,它现在有效。也许有人在查看多个表单集时会发现这里的内容很有用¯\_(ツ)_/¯