Django - 用于更新字段的表单集,表单集无效

Django - formset for updating a field, formset is not valid

我有一个包含姓名和电子邮件字段的模型。我想显示一个具有表单集 (modelformset) 的模板,以更新该模型上给定查询集的电子邮件字段。

models.py

class Student(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    student_first = models.CharField(max_length=30)
    student_last = models.CharField(max_length=30)
    student_number = models.IntegerField()
    email = models.EmailField(max_length=50)

    class Meta:
        ordering = ['student_first']

views.py

def editstudentemail(request, classroom_pk):
    classblock = get_object_or_404(Classroom, pk=classroom_pk)
    students = Student.objects.filter(classroom=classblock).order_by('student_first')
    EditEmailFormSet = modelformset_factory(Student, fields=('email',), extra=0)
    if request.method == 'POST':
        formset = EditEmailFormSet(request.POST, queryset=students)
        if formset.is_valid():
            print("valid")
            instances = formset.save()
        else:
            print("not valid")
        return redirect('gradebook:classroomdetail', classroom_id=classroom_pk)

    formset = EditEmailFormSet(queryset=students)
    context = {'classblock': classblock}
    context['students'] = students
    context['formset'] = formset

    return render(request, 'gradebook/editstudentemail.html', context)

模板:

{% if students %}
  <form method="post">{% csrf_token %}
    {% for ss in students %}
    <div class="row">
            <div class="col-4">
                <b>{{ ss.student_first }}</b>
            </div>
            <div class="col-4">
                {% for form in formset %}
                    {% if forloop.parentloop.counter == forloop.counter %}
                        {{ form|crispy }}<br/>
                    {% endif %}
                {% endfor %}
            </div>
        <hr/>
    </div>
    {% endfor %}
    <input type="submit" value="Save" class="btn btn-outline-primary mt-2" />
  </form>
{% endif %}

模板中的嵌套 for 循环是为了让我可以在编辑电子邮件的表单输入框旁边打印学生姓名。 (也许有更好的方法来做到这一点,也许可以在表单集中包含字段 student_first 但使其不可编辑。)

我想我可能没有正确保存 forms/formset,但我的第一个问题是当我查看此模板时,not valid 被打印到控制台。没有任何错误,formset.is_valid() 正在返回 False

请尝试以下操作

instances = formset.save(commit=False)
for instance in instances:
     instance.save()

基本上单独保存实例

对于这种情况,我需要明确地将 managementform 添加到模板中:

<form method="post">{% csrf_token %}
    {{ formset.management_form }}
    {% for ss in students %}
    ...

我看过 managementform mentioned in the docs 但我不清楚 if/when 它会被添加到模板中。