【发布时间】:2019-11-27 20:40:19
【问题描述】:
我在 django 中遇到了动态表单集的问题
我正在看这个教程,我从中取出了基本代码 https://medium.com/all-about-django/adding-forms-dynamically-to-a-django-formset-375f1090c2b0
但它不能正常工作,因为它不允许我添加更多表单
我认为问题出在 javascript 中,但对它了解不多我无法修复它
它的 html 图像,当我按下“+”按钮时,什么也没发生。例如,如果我将 formset 的“额外”更改为 5,然后按“-”按钮,我期望这项工作。
forms.py
OrdenCompraModelFormset = modelformset_factory(
OrdenCompraProducto,
fields=[
'tipo_producto',
'cantidad',
'fecha_entrega',
'proveedor_surgerido',
],
extra=1,
widgets={
'fecha_entrega': forms.DateInput(attrs=
{'class': 'form-control', 'type': 'date'}),
}
)
views.py
def formv_ordencompra(request):
form=OrdenCompraForm, extra=1)
if request.method == 'GET':
print('0')
formset = OrdenCompraModelFormset(queryset=OrdenCompraProducto.objects.none())
elif request.method == 'POST':
print('1')
formset = OrdenCompraModelFormset(request.POST)
if formset.is_valid():
formset_obj = formset.save(commit=False)
ordencompra = OrdenCompra.objects.create()
for form_obj in formset_obj:
form_obj.orden = ordencompra
form_obj.save()
messages.success(request, f'La orden fue cargada!')
return redirect('.')
else:
print('2')
formset = OrdenCompraModelFormset()
return render(request, 'webapp/formularios/ordencompra.html', {'formset': formset})
ordencompra.html
{% extends 'webapp/base.html' %}
{% load crispy_forms_tags %}
{% load static %}
{% block content_principal %}
<div class="container-fluid">
<h1 class="h3 mb-2 text-gray-800">Cargar "Orden de devolucion"</h1>
<p class="mb-4">Esta orden define quien trae y cuando un recurso que este en obra</p>
<p class="mb-4">¿Cuando cargar?: En el momento en el que se quieran traer recursos desde obra</p>
<hr>
<form class="form-horizontal" method="POST" action="">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<div class="row form-row spacer">
<div class="input-group">
<div class="input-group-append">
<button class="btn btn-success add-form-row">+</button>
<button class="btn btn-danger remove-form-row">-</button>
</div>
{{form|crispy}}
</div>
</div>
<hr>
{% endfor %}
<div class="row spacer">
<div class="">
<button type="submit" class="btn btn-block btn-primary">Create</button>
</div>
</div>
</form>
</div>
{% endblock %}
{% block content_plugins %}
<script type='text/javascript'>
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 cloneMore(selector, prefix) {
var newElement = $(selector).clone(true);
var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
newElement.find(':input:not([type=button]):not([type=submit]):not([type=reset])').each(function() {
var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('label').each(function() {
var forValue = $(this).attr('for');
if (forValue) {
forValue = forValue.replace('-' + (total-1) + '-', '-' + total + '-');
$(this).attr({'for': forValue});
}
});
total++;
$('#id_' + prefix + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
var conditionRow = $('.form-row:not(:last)');
conditionRow.find('.btn.add-form-row')
.removeClass('btn-success').addClass('btn-danger')
.removeClass('add-form-row').addClass('remove-form-row')
.html('<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>');
return false;
}
function deleteForm(prefix, btn) {
var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
if (total > 1){
btn.closest('.form-row').remove();
var forms = $('.form-row');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).find(':input').each(function() {
updateElementIndex(this, prefix, i);
});
}
}
return false;
}
$(document).on('click', '.add-form-row', function(e){
e.preventDefault();
cloneMore('.form-row:last', 'form');
return false;
});
$(document).on('click', '.remove-form-row', function(e){
e.preventDefault();
deleteForm('form', $(this));
return false;
});
</script>
{% endblock %}
【问题讨论】: