Django嵌套表单集动态添加表单
Django nested formsets adding forms dynamically
我正在尝试使用 Django 创建一个调查页面,该页面具有动态添加问题和选项(针对每个问题)的功能。我有以下三个模型 类:调查、问题和选择。
我做了很多研究来弄清楚如何着手实现表单,似乎使用 inline_formsets 的嵌套表单集是正确的方法(I used this tutorial). However, I can't figure out how to add questions and choices dynamically with nested formsets.The JavaScript library that I'm trying to use(This library)没有示例对于嵌套的表单集,我不确定它是否支持它。
这段代码是我目前所拥有的:
forms.py
from django.forms import BaseInlineFormSet
from django.forms import HiddenInput
from django.forms import inlineformset_factory
from django.forms import ModelForm
from .models import *
class SurveyForm(ModelForm):
class Meta:
model = Survey
fields = [
'name',
'description',
]
class BaseQuestionFormset(BaseInlineFormSet):
def add_fields(self, form, index):
super(BaseQuestionFormset, self).add_fields(form, index)
form.nested = QuestionChoiceFormset(
instance=form.instance,
data=form.data if form.is_bound else None,
files=form.files if form.is_bound else None)
def is_valid(self):
result = super(BaseQuestionFormset, self).is_valid()
print(result)
if self.is_bound:
for form in self.forms:
if hasattr(form, 'nested'):
result = result and form.nested.is_valid()
return result
def save(self, commit=True):
for form in self.forms:
form.save(commit=commit)
result = super(BaseQuestionFormset, self).save(commit=commit)
for form in self.forms:
if hasattr(form, 'nested'):
if not self._should_delete_form(form):
form.nested.save(commit=commit)
return result
QuestionFormset = inlineformset_factory(
parent_model=Survey, model=Question, fields='__all__',
formset=BaseQuestionFormset, extra=1)
QuestionChoiceFormset = inlineformset_factory(
parent_model=Question, model=Choice,
fields='__all__', extra=1)
views.py
@login_required
def create(request):
survey = Survey()
if request.method == 'POST':
survey_form = SurveyForm(request.POST, instance=survey)
question_formset = QuestionFormset(
request.POST, prefix='questions', instance=survey)
if survey_form.is_valid() and question_formset.is_valid():
survey_form.save()
question_formset.save()
# url = '/preview/{}'.format(survey.pk)
# return HttpResponseRedirect(url)
else:
survey_form = SurveyForm(instance=survey)
question_formset = QuestionFormset(instance=survey, prefix='questions')
context = {
'survey_form': survey_form,
'question_formset': question_formset,
}
return render(request, 'surveys/create.html', context)
create.html
{% extends 'surveys/base.html' %}
{% load static %}
{% block container %}
<div class="container">
<h1> Create New Survey </h1>
<form method="post">
{% csrf_token %}
{{ question_formset.management_form }}
{{ question_formset.non_form_errors }}
{{ survey_form.as_p }}
<table id='myForm1'>
{% for question_form in question_formset.forms %}
{{ question_form }}
{% if question_form.nested %}
{{ question_form.nested.management_form }}
{{ question_form.nested.non_form_errors }}
<div id='myForm2'>
{% for choice_form in question_form.nested.forms %}
{{ choice_form }}
{% endfor %}
</div>
{% endif %}
{% endfor %}
</table>
<button type="save">Save</button>
</form>
</div>
<script src="{% static "surveys/dist/js/jquery.js" %}"></script>
<script src="{% static "surveys/dist/js/jquery.formset.js" %}"></script>
<script type="text/javascript">
$(function(){
$('#myForm1').formset({
prefix: '{{ question_formset.prefix }}',
formCssClass: 'dynamic-question_formset',
addText: 'add question'
});
$('#myForm2').formset({
prefix: '{{ choice_form.prefix }}',
formCssClass: 'dynamic-choice_form',
addText: 'add choice'
});
})
</script>
{% endblock %}
我最终使用了 this plugin!它有嵌套表单集示例的解释。
我正在尝试使用 Django 创建一个调查页面,该页面具有动态添加问题和选项(针对每个问题)的功能。我有以下三个模型 类:调查、问题和选择。
我做了很多研究来弄清楚如何着手实现表单,似乎使用 inline_formsets 的嵌套表单集是正确的方法(I used this tutorial). However, I can't figure out how to add questions and choices dynamically with nested formsets.The JavaScript library that I'm trying to use(This library)没有示例对于嵌套的表单集,我不确定它是否支持它。 这段代码是我目前所拥有的:
forms.py
from django.forms import BaseInlineFormSet
from django.forms import HiddenInput
from django.forms import inlineformset_factory
from django.forms import ModelForm
from .models import *
class SurveyForm(ModelForm):
class Meta:
model = Survey
fields = [
'name',
'description',
]
class BaseQuestionFormset(BaseInlineFormSet):
def add_fields(self, form, index):
super(BaseQuestionFormset, self).add_fields(form, index)
form.nested = QuestionChoiceFormset(
instance=form.instance,
data=form.data if form.is_bound else None,
files=form.files if form.is_bound else None)
def is_valid(self):
result = super(BaseQuestionFormset, self).is_valid()
print(result)
if self.is_bound:
for form in self.forms:
if hasattr(form, 'nested'):
result = result and form.nested.is_valid()
return result
def save(self, commit=True):
for form in self.forms:
form.save(commit=commit)
result = super(BaseQuestionFormset, self).save(commit=commit)
for form in self.forms:
if hasattr(form, 'nested'):
if not self._should_delete_form(form):
form.nested.save(commit=commit)
return result
QuestionFormset = inlineformset_factory(
parent_model=Survey, model=Question, fields='__all__',
formset=BaseQuestionFormset, extra=1)
QuestionChoiceFormset = inlineformset_factory(
parent_model=Question, model=Choice,
fields='__all__', extra=1)
views.py
@login_required
def create(request):
survey = Survey()
if request.method == 'POST':
survey_form = SurveyForm(request.POST, instance=survey)
question_formset = QuestionFormset(
request.POST, prefix='questions', instance=survey)
if survey_form.is_valid() and question_formset.is_valid():
survey_form.save()
question_formset.save()
# url = '/preview/{}'.format(survey.pk)
# return HttpResponseRedirect(url)
else:
survey_form = SurveyForm(instance=survey)
question_formset = QuestionFormset(instance=survey, prefix='questions')
context = {
'survey_form': survey_form,
'question_formset': question_formset,
}
return render(request, 'surveys/create.html', context)
create.html
{% extends 'surveys/base.html' %}
{% load static %}
{% block container %}
<div class="container">
<h1> Create New Survey </h1>
<form method="post">
{% csrf_token %}
{{ question_formset.management_form }}
{{ question_formset.non_form_errors }}
{{ survey_form.as_p }}
<table id='myForm1'>
{% for question_form in question_formset.forms %}
{{ question_form }}
{% if question_form.nested %}
{{ question_form.nested.management_form }}
{{ question_form.nested.non_form_errors }}
<div id='myForm2'>
{% for choice_form in question_form.nested.forms %}
{{ choice_form }}
{% endfor %}
</div>
{% endif %}
{% endfor %}
</table>
<button type="save">Save</button>
</form>
</div>
<script src="{% static "surveys/dist/js/jquery.js" %}"></script>
<script src="{% static "surveys/dist/js/jquery.formset.js" %}"></script>
<script type="text/javascript">
$(function(){
$('#myForm1').formset({
prefix: '{{ question_formset.prefix }}',
formCssClass: 'dynamic-question_formset',
addText: 'add question'
});
$('#myForm2').formset({
prefix: '{{ choice_form.prefix }}',
formCssClass: 'dynamic-choice_form',
addText: 'add choice'
});
})
</script>
{% endblock %}
我最终使用了 this plugin!它有嵌套表单集示例的解释。