我开始使用 Django 5,并且正在构建一个 Web 项目来组织秘密圣诞老人礼物交换。
我的问题是,使用表单集时,它们不是动态的,因此我无法根据用户的请求创建可变数量的表单。
我有这个表格:
class ParticipanteForm(forms.ModelForm):
class Meta:
model = Participante
fields = ['nombre', 'email']
ParticipanteFormSet = formset_factory(ParticipanteForm)
此型号:
class Participante(models.Model):
sorteo = models.ForeignKey(Sorteo, related_name='participantes', on_delete=models.CASCADE)
nombre = models.CharField(max_length=100)
email = models.EmailField()
这个视图是我渲染表单并保存数据的地方:
def crear_sorteo(request):
sorteo_form = SorteoForm(request.POST or None)
ParticipanteFormSet = formset_factory(ParticipanteForm, extra=3)
participante_formset = ParticipanteFormSet(request.POST or None)
context = {
'sorteo_form': sorteo_form,
'participante_formset': participante_formset,
}
if request.method == 'POST':
if sorteo_form.is_valid():
sorteo = sorteo_form.save() # Save the draw first
if participante_formset.is_valid():
for participante_form in participante_formset:
participante = participante_form.save(commit=False)
participante.sorteo = sorteo # Assign the draw to the participant
participante.save()
return render(request, 'sorteo_realizado.html')
return render(request, 'crear_sorteo.html', context)
如您所见,ParticipanteFormSet = formset_factory(ParticipanteForm, extra=3) 取决于您指定的 extra 数量,这将是要创建的表单数量。但我想在模板中:
<body>
<form action="" method="post">
{% csrf_token %}
{{ sorteo_form }}
{{ participante_formset.management_data }}
{{ participante_formset.as_p }}
<input type="submit" value="Realizar sorteo">
</form>
</body>
有一个添加参与者的按钮,以便用户可以输入任意数量的用户,且参与者至少为 3 人。
我尝试制作一个发布按钮,收到后,
extra
的数量更新为+1,但页面重新加载并且数据丢失。如果有人知道如何实现这一点,那将非常有帮助,提前致谢。
我终于解决了这个问题:在模板中,我们需要添加以下 Django 变量 {{ attendee_formset.management_form }} ,它允许我们使用表单,此外还添加一个按钮来添加将调用 JavaScript 函数的参与者负责添加具有不同 ID 的表单,以便它们最终不会具有相同的名称。最后,模板看起来像这样:
<body>
<style>
.hidden {
display: none;
}
</style>
<form action="" method="post">
{% csrf_token %}
{{ sorteo_form }}
{{ participante_formset.management_form }}
<div id='participante-form-list'>
{% for form in participante_formset %}
<div class='participante-form'>
{{ participante_formset.as_p }}
</div>
{% endfor %}
</div>
<div id='empty-form' class='hidden'>{{ participante_formset.empty_form.as_p }}</div>
<button id='add-more' type='button'>+ participant</button>
<input type="submit" value="Carry out draw">
</form>
</body>
与 JavaScript 一起:
<script>
const addMoreBtn = document.getElementById('add-more')
const totalNewForms = document.getElementById('id_participante-TOTAL_FORMS')
addMoreBtn.addEventListener('click', add_new_form)
function add_new_form(event) {
if (event) {
event.preventDefault()
}
const currentParticipantes = document.getElementsByClassName('participante-form')
let currentFormCount = currentParticipantes.length
const formCopyTarget = document.getElementById('participante-form-list')
const copyEmptyFormEL = document.getElementById('empty-form').cloneNode(true)
copyEmptyFormEL.setAttribute('class', 'participante-form')
copyEmptyFormEL.setAttribute('id', `form-${currentFormCount}`)
const regex = new RegExp('__prefix__', 'g')
copyEmptyFormEL.innerHTML = copyEmptyFormEL.innerHTML.replace(regex,
currentFormCount)
totalNewForms.setAttribute('value', currentFormCount + 1)
formCopyTarget.append(copyEmptyFormEL)
}
</script>
最后,在视图中,我们只需要声明formset并将extra设置为0即可:
ParticipanteFormSet = formset_factory(ParticipanteForm, extra=0)
感谢以下视频,我得到了此代码,这对您和我来说肯定都会非常有帮助: