我使用formset将数据输入数据库,但由于某种原因,每当我在终端中测试并调用.is_valid((时,它都不会验证。无论我尝试什么,它都会返回false。这是我的views.py和forms.py中的代码。任何帮助都将不胜感激!
# Advanced Subjects (Advanced Biology)
def form_5_entry_biology_view(self, request):
current_teacher = User.objects.get(email=request.user.email)
logged_school = current_teacher.school_number
students_involved = User.objects.get(school_number=logged_school).teacher.all()
data = {"student_name": students_involved}
formset_data = AdvancedStudents.objects.filter(class_studying="Form V", combination="PCB")
student_formset = formset_factory(AdvancedBiologyForm, extra=0)
initial = []
for element in formset_data:
initial.append({"student_name": element})
formset = student_formset(request.POST or None, initial=initial)
print(formset.is_valid())
context = {
"students": students_involved,
"formset": formset,
"class_of_students": "Form V",
"subject_name": "Advanced Biology",
}
return render(request, "analyzer/marks_entry/marks_entry_page.html", context)
这是我的表格.py
class AdvancedBiologyForm(forms.ModelForm):
student_name = forms.CharField()
class Meta:
model = ResultsALevel
fields = ('student_name', 'advanced_biology_1', 'advanced_biology_2',
'advanced_biology_3',)
在使用request.POST
和is_valid()
之前,您可能需要检查是否真的有张贴请求,或者页面是否刚刚被查看:
def form_5_entry_biology_view(self, request):
current_teacher = User.objects.get(email=request.user.email)
logged_school = current_teacher.school_number
students_involved = User.objects.get(school_number=logged_school).teacher.all()
data = {"student_name": students_involved}
formset_data = AdvancedStudents.objects.filter(class_studying="Form V", combination="PCB")
# Here you are creating the formset using the model
student_formset = formset_factory(AdvancedBiologyForm, extra=0)
# Here you are generating your initial data
initial = []
for element in formset_data:
initial.append({"student_name": element})
# Here you are using the initial data to create pre-populated
# forms with it using the formset.
# These forms will be displayed when the page loads.
formset = student_formset(initial=initial)
context = {
"students": students_involved,
"formset": formset,
"class_of_students": "Form V",
"subject_name": "Advanced Biology",
}
# But if the user hits the "submit"-Button...
if request.method == 'POST':
# ... you don't want to have the formset with your
# initial data. Instead you want the entries by the user
# which are transmitted in request.POST to populate the
# formset forms.
formset = student_formset(request.POST or None)
# Now you can validate the formset with the fields which
# got input the the user; not the "initial" data like in
# your original code
if formset.is_valid():
# This runs formset validation.
# You can define your own formset validations like
# you would for models/forms.
for form in formset:
# And / Alternatively:
# you could in theory also add another "if form.is_valid():" in here
# This would trigger any validation on the
# model/form; not the validators on the formset.
form.save()
return HttpResponseRedirect(...
return render(request, "analyzer/marks_entry/marks_entry_page.html", context)
否则,您可能会在未绑定的表单上调用is_valid()
。来自Django文档:
如果表单是使用POST请求提交的,则视图将再次创建一个表单实例,并用请求中的数据填充它:form=NameForm(request.POST(这被称为"将数据绑定到表单"(现在是绑定表单(。
基本上,如果表单为空,它将被解除绑定,如果表单中填充了数据,它将在POST后被绑定。当你打开一个页面并立即尝试";is_valid(("当你检查一个空表单是否有效时,它基本上总是错误的;这可能永远不会发生。
指出错误:
formset = student_formset(request.POST or None, initial=initial)
print(formset.is_valid())
这是无效的。因为初始值不等于用"0"填充表单字段;真实的";价值观因此,它试图用request.POST or None
填充表单中的字段。但你没有if request.method == 'POST':
条件。因此,您的代码将在到达最后一行代码(即显示页面的return语句(之前运行一遍。这意味着您的代码在用户看到页面之前就验证了request.POST or None
。因此,用户不可能已经输入数据并点击提交。这意味着没有POST请求,所以它总是变成None
。因此,您基本上是在一个没有字段值的表单上调用is_valid()
,这会导致验证失败。
第1版:我刚刚注意到你在forms.py
中写了:
fields = ('student_name', 'advanced_biology_1', 'advanced_biology_2',
'advanced_biology_3',)
这应该是一个列表:
fields = ['student_name', 'advanced_biology_1', 'advanced_biology_2',
'advanced_biology_3',]
编辑2:修复了错误的变量名第3版:添加了大量注释,以澄清代码中发生的情况第四版:更清楚地指出了问题的原因。