Django创建投票时如何实现可动态添加任意数量Choice ModelForm表单
实现动态新增投票选项的方案
你需要借助Django的Formset功能处理多组Choice表单提交,配合前端JS实现动态新增入口,总共分三步修改:
第一步:修改forms.py,创建选项表单集
我们用formset_factory生成可批量提交的Choice表单集合:
from django import forms from django.forms import formset_factory from .models import Question, Choice class NewPollForm(forms.ModelForm): class Meta: model = Question labels = { "questionText":"投票问题" } fields = ("questionText",) class NewChoicesForm(forms.ModelForm): class Meta: model = Choice labels = { "choiceText":"选项内容" } fields = ("choiceText",) # 创建选项表单集,默认初始显示2个选项,允许提交时动态新增 ChoiceFormSet = formset_factory( NewChoicesForm, extra=2, # 初始显示的空选项数量 can_delete=False, # 不需要删除功能可以设为False min_num=2, # 最少需要填2个选项 validate_min=True )
第二步:修改视图函数,处理表单集提交
需要调整原视图逻辑,批量保存所有提交的选项:
from django.shortcuts import render, redirect from django.utils import timezone from .forms import NewPollForm, ChoiceFormSet def newpoll(request): if not request.user.is_authenticated: return redirect("users:signup") if request.method == "POST": qform = NewPollForm(request.POST) # 用POST数据初始化表单集 choice_formset = ChoiceFormSet(request.POST) if qform.is_valid() and choice_formset.is_valid(): # 先保存问题 newpoll = qform.save(commit=False) newpoll.user = request.user newpoll.save() # 批量保存所有选项 for form in choice_formset: # 跳过用户没填的空选项 if form.cleaned_data.get('choiceText'): choice = form.save(commit=False) choice.question = newpoll choice.save() return redirect("polls:details", pollid=newpoll.pk) else: qform = NewPollForm() choice_formset = ChoiceFormSet() return render(request, "polls/newpoll.html", {"qform": qform, "choice_formset": choice_formset})
第三步:修改模板newpoll.html,添加动态新增按钮
需要先渲染表单集的管理字段(必加,否则Django无法识别表单数量),再添加JS实现新增逻辑:
<form method="POST"> {% csrf_token %} <!-- 渲染问题表单 --> <div> {{ qform.as_p }} </div> <!-- 表单集管理字段,必须保留 --> {{ choice_formset.management_form }} <!-- 所有选项输入框的容器 --> <div id="choices-container"> {% for form in choice_formset %} <div class="choice-item"> {{ form.as_p }} </div> {% endfor %} </div> <!-- 新增按钮 --> <button type="button" id="add-choice-btn">+ 新增另一个选项</button> <button type="submit">创建投票</button> </form> <script> // 动态新增选项逻辑 document.getElementById('add-choice-btn').addEventListener('click', function() { const container = document.getElementById('choices-container'); const items = container.querySelectorAll('.choice-item'); const lastItem = items[items.length - 1]; const newItem = lastItem.cloneNode(true); // 更新新表单的序号 const regex = new RegExp(`form-(\\d+)-`, 'g'); const newIndex = items.length; newItem.innerHTML = newItem.innerHTML.replace(regex, `form-${newIndex}-`); // 清空新输入框的内容 newItem.querySelector('input').value = ''; container.appendChild(newItem); // 更新表单集的总数量 document.getElementById('id_form-TOTAL_FORMS').value = newIndex + 1; }); </script>
内容的提问来源于stack exchange,提问作者mohammed hashim
相关产品推荐
相关产品推荐

