【发布时间】:2021-11-29 14:24:18
【问题描述】:
我有一个包含姓名和电子邮件字段的模型。我想显示一个具有表单集(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,但使其不可编辑。)
我想我可能没有正确保存表单/表单集,但我的第一个问题是当我查看此模板时,not valid 会打印到控制台。没有任何错误,formset.is_valid() 正在返回 False。
【问题讨论】: