如何解决Django - 问卷 - ModelFormSet - 无法分配
好的,我正在学习使用 Django 创建小型问卷的教程。
用户可以使用不同的多项选择问题创建调查。由于是多项选择题,用户还可以设置问题的选项。
然后,“调查对象”可以开始调查,选择他或她喜欢的问题并提交表格。
我想每页只显示一个问题,所以我正在尝试使用 modelformset_factory 并使用分页器中的构建实现分页。
表单正确呈现,用户可以提交答案,但是,表单在“formset.is_valid()”之前失败,我就是不知道为什么;
ValueError at /surveys/1/submit/4/
不能分配“'2'”:“Answer.option”必须是“Option”实例。
所以我不能保存一个整数,我必须以某种方式将整数与选项模型中的 id 相关联......但我还不能访问cleaned_data,所以我想我在这里遗漏了一些东西。我是否忘记了表单集中的某些内容?
我已经关注了一段时间了,所以感谢您的帮助。
#Views
def submit(request,survey_pk,sub_pk):
# Let's retrieve the survey which is created by the survey-taker
try:
survey = Survey.objects.prefetch_related("question_set__option_set").get(
pk=survey_pk,is_active=True
)
except Survey.DoesNotExist:
raise Http404()
try:
submission = survey.submission_set.get(pk=sub_pk,is_complete=False)
except Submission.DoesNotExist:
raise Http404()
# Retrieve all question associated with this survey
questions = survey.question_set.all()
# Get all related options from the questions
options = [q.option_set.all() for q in questions]
form_kwargs = {"empty_permitted": False,"options": options,}
# Setup a formset utilizing a ModelFormSet
AnswerFormset = modelformset_factory(
Answer,form=AnswerModelForm,formset=BaseAnswerFormSet,exclude=(),extra=len(questions),)
if request.method == "POST":
print("Request.POST",request.POST)
# This is where the problem starts
formset = AnswerFormset(request.POST,form_kwargs=form_kwargs)
print("Formset: ",formset)
if formset.is_valid():
print("Formset is valid")
with transaction.atomic():
for form in formset:
Answer.objects.create(
option_id=form.cleaned_data["option"],submission_id=sub_pk,)
submission.is_complete = True
submission.save
return redirect("survey-thanks",pk=survey_pk)
else:
formset = AnswerFormset(form_kwargs=form_kwargs)
print(form_kwargs)
question_forms = zip(questions,formset)
return render(
request,"survey/submit.html",{
"survey": survey,"question_forms": question_forms,"formset": formset
}
)
#forms
# Setup a Modelformset
class AnswerModelForm(forms.ModelForm):
class Meta:
model = Answer
fields = "option",def __init__(self,*args,**kwargs):
options = kwargs.pop("options")
# Options must be a list of Option objects
choices = {(o.pk,o.text) for o in options}
super().__init__(*args,**kwargs)
option_field = forms.ChoiceField(choices=choices,widget=forms.RadioSelect,required=True)
self.fields["option"] = option_field
class BaseAnswerFormSet(forms.BaseFormSet):
def get_form_kwargs(self,index):
kwargs = super().get_form_kwargs(index)
kwargs["options"] = kwargs["options"][index]
return kwargs
#models
class Answer(models.Model):
"""An answer a survey's questions."""
submission = models.ForeignKey(Submission,on_delete=models.CASCADE)
option = models.ForeignKey(Option,on_delete=models.CASCADE)
解决方法
option_id=form.cleaned_data["option"],
是嫌疑人,它可能需要一个选项实例,即使您试图传递 id。尝试将 option_id 更改为 option__id 并将 form.cleaned_data["option"] 显式设置为 int。另一种方法是手动拉取选项并直接传递:
option = Option.object.get(id=int(form.cleaned_data["option"]))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。