我成功地设法创建了一个表单,可以将新行添加到由两个表单集组成的表单中。
出现新字段,我可以输入并提交数据。但是在第一次提交后,这些字段显示为empthy。如果我重新输入数据,则值将正确传递。所以我在add
- 脚本的末尾添加了一个重新验证,并且表单通过了。但是没有数据被添加到模型中,所以我认为数据是在第一个approche中没有传递的。
感谢您的帮助!
观点:
def pruefplan(request):
class RequiredFormSet(BaseFormSet):
def __init__(self, *args, **kwargs):
super(RequiredFormSet, self).__init__(*args, **kwargs)
for form in self.forms:
form.empty_permitted = False
PruefschrittAttributivFormset = formset_factory(
PruefschrittAttributivForm,
max_num=10,
formset=RequiredFormSet,
)
PruefschrittVariabelFormset = formset_factory(
PruefschrittVariabelForm,
max_num=10,
formset=RequiredFormSet,
)
if request.method == 'POST': # If the form has been submitted...
# A form bound to the POST data
pruefplan_form = PruefplanForm(request.POST)
# Create a formset from the submitted data
pruefschritt_attributiv_formset = PruefschrittAttributivFormset(
request.POST,
request.FILES,
prefix='attr',
)
pruefschritt_variable_formset = PruefschrittVariabelFormset(
request.POST,
request.FILES,
prefix='var',
)
if (
pruefplan_form.is_valid()
and
pruefschritt_attributiv_formset.is_valid()
and
pruefschritt_variable_formset.is_valid()
):
pruefplan = pruefplan_form.save()
for form in pruefschritt_attributiv_formset.forms:
attributiv_item = form.save(commit=False)
attributiv_item.pruefplan = pruefplan
attributiv_item.save()
for form in pruefschritt_variable_formset.forms:
variable_item = form.save(commit=False)
variable_item.pruefplan = pruefplan
variable_item.save()
return HttpResponseRedirect('') # Redirect to a 'success' page
else:
pruefplan_form = PruefplanForm()
pruefschritt_attributiv_formset = PruefschrittAttributivFormset(
prefix='attr')
pruefschritt_variable_formset = PruefschrittVariabelFormset(
prefix='var')
# For CSRF protection
# See http://docs.djangoproject.com/en/dev/ref/contrib/csrf/
pruefplan = Pruefplan.objects.all()
c = {'pruefplan': pruefplan,
'pruefplan_form': pruefplan_form,
'pruefplan_attributiv_formset': pruefschritt_attributiv_formset,
'pruefplan_variable_formset': pruefschritt_variable_formset,
}
c.update(csrf(request))
return render_to_response('qpruefung/pruefplan.html', c)
模板:
<div class="tab-pane fade" id="erfassung">
<link rel="stylesheet" href="{% static 'css/jquery-ui.css' %}">
<script src="{% static 'js/jquery-ui.js' %}"></script>
<div class=container style="width: 80%">
<script>
$(document).ready(function () {
// Code adapted from http://djangosnippets.org/snippets/1389/
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+-)');
var replacement = prefix + '-' + ndx + '-';
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex,
replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function addForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
// You can only submit a maximum of 10 todo items
if (formCount < 1000) {
// Clone a form (without event handlers) from the first form
var row = $(".item:first").clone(false).get(0);
// Insert it after the last form
$(row).removeAttr('id').hide().insertAfter(".item:last").slideDown(300);
// Remove the bits we don't want in the new row/form
// e.g. error messages
$(".errorlist", row).remove();
$(row).children().removeClass("error");
// Relabel or rename all the relevant bits
$(row).children().children().each(function () {
updateElementIndex(this, prefix, formCount);
$(this).val("");
});
// Add an event handler for the delete item/form link
$(row).find(".delete").click(function () {
return deleteForm(this, prefix);
});
// Update the total form count
$("#id_" + prefix + "-TOTAL_FORMS").val(formCount + 1);
window.location.href = "#erfassung"
} // End if
else {
alert("Sorry, you can only enter a maximum of ten items.");
}
return false;
}
function addvarForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
// You can only submit a maximum of 10 todo items
if (formCount < 1000) {
// Clone a form (without event handlers) from the first form
var row = $(".item_var:first").clone(false).get(0);
// Insert it after the last form
$(row).removeAttr('id').hide().insertAfter(".item_var:last").slideDown(300);
// Remove the bits we don't want in the new row/form
// e.g. error messages
$(".errorlist", row).remove();
$(row).children().removeClass("error");
// Relabel or rename all the relevant bits
$(row).children().children().each(function () {
updateElementIndex(this, prefix, formCount);
$(this).val("");
});
// Add an event handler for the delete item/form link
$(row).find(".delete").click(function () {
return deleteForm(this, prefix);
});
// Update the total form count
$("#id_" + prefix + "-TOTAL_FORMS").val(formCount + 1);
// Revalidate the fields
$('myForm').data('validator', null);
$.validator.unobtrusive.parse($('myForm'));
} // End if
else {
alert("Sorry, you can only enter a maximum of ten items.");
}
return false;
}
// Register the click event handlers
$("#add_attr").click(function () {
return addForm(this, "attr");
});
$("#add_var").click(function () {
return addvarForm(this, "var");
});
});
</script>
</head>
<body>
<h2>Prüfplan erstellen</h2>
<form id="myForm" action="" method="POST" class="bootstrap">{% csrf_token %}
<div class="section">
{{ pruefplan_form | crispy}}
</div>
<h2>Pruefschritte attributiv</h2>
{{ pruefplan_attributiv_formset.management_form }}
{% for form in pruefplan_attributiv_formset.forms %}
<div class="item">
{{ form | crispy }}
</div>
{% endfor %}
<p><a id="add_attr" href="#">Prüfpunkt hinzufügen</a></p>
<h2>Pruefschritte variabel</h2>
{{ pruefplan_variable_formset.management_form }}
{% for form in pruefplan_variable_formset.forms %}
<div class="item_var">
{{ form | crispy }}
</div>
{% endfor %}
<p><a id="add_var" href="#">Prüfpunkt hinzufügen</a></p>
<input type="submit" value=" Submit " />
</form>
</body>
</div>
POST dict:
<QueryDict: {u'attr-0-prueftext_attributiv': [u'1', u'2'], u'var-INITIAL_FORMS':
[u'0'], u'pruefmittel': [u'tt'],
u'var-0-obere_grenze': [u'1'],
u'var-0-prueftext_variabel': [u'1'], u'prueflink': [u'https://link.local'], u'var-0-soll': [u'1'], u'var-0-untere_grenze': [u'1'], u'pruefdatei': [u''], u'pruefintervall_obere_grenze': [u'12'],
u'attr-MIN_NUM_FORMS': [u'0'], u'pruefintervall': [u'21'],
u'pruefbild': [u''], u'csrfmiddlewaretoken': [u'2mw1tktwBUiheZ422Q2jlEygRQ18DuII'],
u'var-MAX_NUM_FORMS': [u'10'], u'pruefplannummer': [u'56'], u'lagerort': [u'tt'], u'attr-TOTAL_FORMS': [u'2'],
u'pruefintervall_untere_grenze': [u'12'], u'attr-MAX_NUM_FORMS': [u'10'], u'pruefanweisung': [u'tt'],
u'var-MIN_NUM_FORMS': [u'0'],
u'attr-INITIAL_FORMS': [u'0'],
u'var-TOTAL_FORMS': [u'1']}>
更新
所以我发现了问题:
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+-)');
var replacement = prefix + '-' + ndx + '-';
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex,
replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
不更新ID或名称。然而,“For”已更新。如果我纠正这个问题,一切都会变得很好。
那么我该如何解决这个问题呢?
答案 0 :(得分:0)
此行帽将替换为:
$(row).children().children().each(function () {
updateElementIndex(this, prefix, formCount);
$(this).val("");
$(row).children().children().children().each(function () {
updateElementIndex(this, prefix, formCount);
$(this).val("");
由于HTML生成了一个带有3个嵌套元素的div
<div id="div_id_attr-0-prueftext_attributiv" class="form-group">
<label class="control-label " for="id_attr-0-prueftext_attributiv">
</label>
<div class="controls ">
<input id="id_attr-1-prueftext_attributiv" class="textinput
extInput form-control" type="text" name="attr-
1-prueftext_attributiv" maxlength="64"></input>
</div>
</div>
使用两个.children()替换只能达到标签和控制而不是输入。