如何使用模型实例和默认字段值填充 Django 模型表单集

How to populate a django Model FormSet with Model instances AND default field values

问题是如何使用查询集填充模型表单集的每个表单,以及如何向表单集中的未绑定表单提供初始数据。为什么?我有一个名为 Answer 的模型。我想为一个问题模型创建许多答案,每个问题都在另一个模型的一个部分中。在问题详细信息页面中,我已经知道 Answer 对象应该属于的 Section 和 Question,这些最终只会呈现为隐藏字段,但我需要它们来保存 Answer 对象。

我的模型(减少到基本字段):

class Section(models.Model):
    section = models.CharField(max_length=100)

    def __str__(self):
        return self.section


class Question(models.Model):
    question = models.CharField(max_length=500)
    section = models.ForeignKey(Section, on_delete=models.CASCADE)

    def __str__(self):
        return self.question


class Answer(models.Model):
    answer = models.CharField(max_length=200, null=True, default='')
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    section = models.ForeignKey(Section, on_delete=models.CASCADE)

    def __str__(self):
        return self.answer

我的表格:

class AddAnswerForm(forms.ModelForm):

    class Meta:
        model = Answer
        fields = ['answer', 'question', 'section']

我想使用模型表单集来执行此操作,因为用户应该能够继续添加答案,并且还可以编辑之前给出的答案。我查看了关于如何使用查询集来限制结果的 docs, which for django are excellent, and found how to add initial data here. Initially, the template was displaying ALL Answer objects, which I saw is done by default, until I see this。然后尝试使用

initial={'section': section, 'question': question}

创建了一个KeyError

那么如何为表单集中的每个答案提供 sectionquestion 的默认值,同时使用先前保存的答案对象填充绑定的表单集表单?

答案在 docs and on Whosebug 中,经过大量搜索和尝试后发现非常简单。对我来说,它最终变成了 [ ]!

views.py

    AnswerFormSet = modelformset_factory(Answer, form=AddAnswerForm)
    formset = AnswerFormSet(request.POST or None, 
                            initial=[{'section': section, 'question': question}], 
                            queryset=Answer.objects.filter(question=question))

    if formset.is_valid():
        formset.save()
        return redirect('question', question.pk, question.question)

现在它工作正常,但如果问题是重复的,或者如果有更好的方法,我将不胜感激反馈。经过几个小时的努力,我认为它对处于类似情况的其他人有用。

编辑
我对模型表单集如此着迷,以至于我没有阅读有关它们所基于的文档,formsets!所有相关信息都在那里。故事的道德启示。 阅读文档!