【发布时间】:2021-02-23 05:43:08
【问题描述】:
情况:
我在同一页面上有 3 个表单,在这三个表单中,我设置了 ajax 调用来根据表单中的选择来获取可用的类,从而允许他们在提交之前选择一个课程。我已经在应用程序的另一部分执行此操作,它似乎可以正常工作,但在这里却不行。
在解决错误之前,这里是代码。 所以我有以下路线:
守则:
@bp.route('/edit_student/<academy>/<name>', methods=['GET','POST'])
@login_required
@group_required(['Master', 'Upper Management', 'Management', 'Admin'])
def edit_student(name, academy):
academy = Academy.query.filter_by(name=academy).first()
student = Student.query.filter_by(name=name).filter_by(academy_id=academy.id).first()
current_lesson = Lessons.query.filter_by(id=student.class_id).first()
length_of_class = LengthOfClass.query.filter_by(id=current_lesson.length_of_class).first()
type_of_class = TypeOfClass.query.filter_by(id=current_lesson.type_of_class).first()
options_121 =['121-General English', '121-Exam Class', '121-Business English', '121-Children', 'In-Company-121']
step = None
if not current_user.is_master() and current_user.position != "Upper Management":
if current_user.academy_id != academy.id:
flash('You can only remove people from your own academy.')
return redirect(url_for('students.student_profile', name=student.name, academy=academy.name))
if type_of_class.name == 'Group General English':
step = Step.query.filter_by(id=student.step_id).first()
form = EditStudentForm(obj=student.id)
form2 = AdditionalClassForm(obj=student.id)
form3 = AdditionalClassForm2(obj=student.id)
# Fill current form details
form.name.data = student.name
form.phone.data = student.phone
form.email.data = student.email
form.comment.data = student.comment
form.lengthofclass.data = length_of_class.name
form.academy.data = academy.name
form.typeofclass.data = type_of_class.name
if step:
form.step.data = step.name
form.lesson.choices = [(current_lesson.id, '{} Students: {}/8 {}'.format(current_lesson.name, current_lesson.amount_of_students, current_lesson.time))]
if student.student_on_class:
link = Studentonclass.query.filter_by(id=student.student_on_class).first()
lesson = Lessons.query.filter_by(student_on_class=link.id).first()
acad = Academy.query.filter_by(id=lesson.academy_id).first()
length_of = LengthOfClass.query.filter_by(id=lesson.length_of_class).first()
type_of = TypeOfClass.query.filter_by(id=lesson.type_of_class).first()
if type_of.name == 'Group General English':
step_additional = Step.query.filter_by(id=lesson.step_id).first()
form2.step.data = step_additional.name
form2.lengthofclass.data = length_of.name
form2.academy.data = acad.name
form2.typeofclass.data = type_of.name
form2.lesson_.choices = [(lesson.id, '{} Students: {}/8 {}'.format(lesson.name, lesson.amount_of_students, lesson.time))]
if student.student_on_class2:
link = Studentonclass.query.filter_by(id=student.student_on_class2).first()
lesson = Lessons.query.filter_by(student_on_class=link.id).first()
acad = Academy.query.filter_by(id=lesson.academy_id).first()
length_of = LengthOfClass.query.filter_by(id=lesson.length_of_class).first()
type_of = TypeOfClass.query.filter_by(id=lesson.type_of_class).first()
if type_of.name == 'Group General English':
step_additional = Step.query.filter_by(id=lesson.step_id).first()
form3.step.data = step_additional.name
form3.lengthofclass.data = length_of.name
form3.academy.data = acad.name
form3.typeofclass.data = type_of.name
form3.lesson3.data = [(lesson.id, '{} Students: {}/8 {}'.format(lesson.name, lesson.amount_of_students, lesson.time))]
if form.validate_on_submit():
if form.typeofclass.data == 'Group General English':
print(form.lesson.data)
print(form.lesson.choices)
if form.lesson.data == 'None':
flash('You must have a lesson value')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
if form.lesson.data == None:
flash('You must have a lesson value')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
if student.name != form.name.data:
student.name = form.name.data
if student.phone != form.phone.data:
student.phone = form.phone.data
if student.email != form.email.data:
student.email = form.email.data
if student.comment != form.comment.data:
student.comment = form.comment.data
if academy.name != form.academy.data:
new_academy = Academy.query.filter_by(name=form.academy.name).first()
student.academy_id = new_academy.id
if current_lesson.id != form.lesson.data:
new_lesson = Lessons.query.filter_by(id=form.lesson.data).first()
student.class_id = new_lesson.id
if type_of_class.name != form.typeofclass.data:
if form.typeofclass.data == 'Group General English':
student.step_id = new_lesson.step_id
if step:
if step.name != form.step.data:
step = Step.query.filter_by(name=form.step.data).first()
student.step_id = step.id
student.user_id = current_user.id
elif form.typeofclass.data in options_121:
# Create 121 class here
lesson_name = get_name(name=form.name.data, academy=academy.id, types=form.typeofclass.data, companyname=form.companyname.data)
if form2.academy.data and form2.typeofclass.data and form2.lengthofclass.data and form2.lesson_.data:
if form2.typeofclass.data == 'Group General English':
if form2.lesson_.data == 'None':
flash('You must have a lesson in order to add an additional lesson')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
if step:
if form2.step.data != step.name:
if int(form2.step.data) <= step.name - 3 or int(form2.step.data) >= step.name + 3:
flash('You cannot place a student in such a different step to their level')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
# handling additional classes
acad = Academy.query.filter_by(name=form2.academy.data).first()
length_of = LengthOfClass.query.filter_by(name=form2.lengthofclass.data).first()
type_of = TypeOfClass.query.filter_by(name=form2.typeofclass.data).first()
additional_lesson = Lessons.query.filter_by(id=form2.lesson_.data).first()
if acad.name != 'Online' and acad.name != academy.name:
flash('Student can only be part of two different academy classes if one academy is online!')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
if type_of.name == type_of_class.name and additional_lesson.id == current_lesson.id:
flash('You cannot add them to a second class to the same class')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
if additional_lesson.student_on_class:
link = Studentonclass.query.filter_by(id=additional_lesson.student_on_class).first()
student.student_on_class = link.id
additional_lesson.amount_of_students = additional_lesson.amount_of_students + 1
db.session.commit()
else:
link = Studentonclass()
db.session.add(link)
db.session.commit()
additional_lesson.student_on_class = link.id
student.student_on_class = link.id
additional_lesson.amount_of_students = additional_lesson.amount_of_students + 1
db.session.commit()
elif form2.typeofclass.data in options_121:
# Create 121 class here
lesson_name = get_name(name=form.name.data, academy=academy.id, types=form2.typeofclass.data, companyname=form2.companyname_.data)
if form3.academy.data and form3.typeofclass.data and form3.lengthofclass.data and form3.lesson3.data:
if form3.typeofclass.data == 'Group General English':
if form3.lesson3.data == 'None':
flash('You must have a lesson in order to add second additional lesson.')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
if form3.lesson3.data == None:
flash('You must have a lesson in order to add second additional lesson.')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
acad = Academy.query.filter_by(name=form3.academy3.data).first()
length_of = LengthOfClass.query.filter_by(name=form3.lengthofclass3.data).first()
type_of = TypeOfClass.query.filter_by(name=form3.typeofclass3.data).first()
additional_lesson = Lessons.query.filter_by(id=form3.lesson3.data).first()
if acad.name != 'Online' and acad.name != academy.name:
flash('Student can only be part of two different academy classes if one academy is online!')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
if type_of.name == type_of_class.name and additional_lesson.id == current_lesson.id:
flash('You cannot add them to a second class to the same class')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
if type_of.name == form2.typeofclass.name and additional_lesson.id == form2.lesson_.data:
flash('You cannot add them to a second class to the same class')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
if step:
if form3.step.data != None and form3.step.data != step.name or form2.step.data != None and form3.step.data != form2.step.data:
if int(form3.step.data) <= step.name - 3 or int(form3.step.data) >= step.name + 3:
flash('Please Keep the step levels in all classes as close to eachother as possible.')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
if additional_lesson.student_on_class2:
link = Studentonclass2.query.filter_by(id=additional_lesson.student_on_class2).first()
student.student_on_class2 = link.id
additional_lesson.amount_of_students = additional_lesson.amount_of_students + 1
db.session.commit()
else:
link = Studentonclass2()
db.session.add(link)
db.session.commit()
additional_lesson.student_on_class2 = link.id
student.student_on_class2 = link.id
additional_lesson.amount_of_students = additional_lesson.amount_of_students + 1
db.session.commit()
elif form3.typeofclass.data in options_121:
# Create 121 class here
lesson_name = get_name(name=form.name.data, academy=academy.id, types=form3.typeofclass3.data, companyname=form3.companyname3.data)
db.session.commit()
flash('Student Editted')
return redirect(url_for('students.edit_student', name=student.name, academy=academy.name))
return render_template('students/edit_student.html', title="Edit Student", form=form, form2=form2, form3=form3, student=student, student_id=student.id, academy=academy)
这是处理页面显示和提交后处理表单的路由。 现在关于这是如何处理的,我有以下发送 ajax 调用:
function run_ajax(form_id, lesson_name, lesson_class, stepfield_id, examfield_id, kidfield_id, agefield_id, type_of_class) {
lesson_class.show('slow')
lesson_name.show('slow')
// if form_id = additional turn url to one route or the other create different route for each ajax call
if (form_id === '#form1') {
var url_is = "/get_classes_edit/" + {{student_id | safe}}
} else if (form_id === '#form2') {
var url_is = "/get_classes_add1"
} else if (form_id === '#form3') {
var url_is = "/get_classes_add2"
}
var form = $(form_id).serialize();
if (step_options.includes(type_of_class) && stepfield_id.val() != 'None') {
$.ajax(
{
type: 'POST',
url: url_is,
data: $(form_id).serialize(),
context: form,
success: function(selectOptions){
lesson_name.empty();
console.log(selectOptions.length)
if (selectOptions.length == 0) {
lesson_name.append(
$("<option></option>")
.attr("value", 'None')
.text('No classes of this type are available please create a class.'))
}
for (var i = 0; i < selectOptions.length; i++){
lesson_name.append(
$("<option></option>")
.attr("value", selectOptions[i]['lesson_id'])
.text(selectOptions[i]['lesson_name'] + ' Students: ' + selectOptions[i]['amount_of_students'] + '/8' + ' ' + selectOptions[i]['lesson_time']))
}
}
});
} else if (exam_options.includes(type_of_class) && examfield_id.val() != 'None'){
alert('Please select the level')
} else if (kids_options.includes(type_of_class) && kidfield_id.val() != 'None' || agefield_id.val() != 'None'){
alert('Please select the level')
}
}
这个 ajax 调用是用以下行调用的:
run_ajax('#form2', $('#lesson_name2'), $('.lesson_'), $('#step2'), $('#exam2'), $('#kid2'), $('#agerange2'), type_of2)
现在有了这些,每个 url 都由一个类似这样设置的路由处理:
@bp.route('/get_classes_edit/<student>', methods=['POST'])
def get_classes_edit(student):
student = Student.query.filter_by(id=student).first()
form = EditStudentForm(obj=student.id)
if form.submit():
academy = Academy.query.filter_by(name=form.academy.data).first()
length_of = LengthOfClass.query.filter_by(name=form.lengthofclass.data).first()
type_of_class = TypeOfClass.query.filter_by(name=form.typeofclass.data).first()
step = Step.query.filter_by(name=form.step.data).first()
choices = []
if form.typeofclass.data == 'Group General English':
lessons = Lessons.query.filter_by(academy_id=academy.id)\
.filter_by(length_of_class=length_of.id)\
.filter_by(type_of_class=type_of_class.id)\
.filter_by(step_id=step.id).all()
for i in lessons:
if i.amount_of_students < 8:
choice_final = {
'lesson_id': i.id,
'lesson_name': i.name,
'amount_of_students': i.amount_of_students,
'lesson_time': i.time
}
choices.append(choice_final)
# return none so that can display message
return jsonify(choices)
错误:
这样就完全没有回溯错误,而是性能错误,因为它没有按预期工作。我已经尝试打印多个东西来确定里面发生了什么。
现在当我打印时:
print(form.lesson.data)结果是None。
print(form.lesson.choices)结果是choices[(6, 'STA-1'),(8, 'SMA-2')]。
print(form.lesson.raw_data)结果是[]。
这与工作的人不同,因为我是从工作的人那里收到的:
print(form.lesson.data)结果是'6'。
print(form.lesson.choices)结果是choices[]。
ajax 调用中的整个想法是将 id 设置为选择字段内标签中的值并通过 form.lesson.data 接收它以便使用它,但是我可以读取选项但不能读取价值?
问题:
为什么form.lesson.data 会返回None,而form.lesson.choices 显然可以读取选项中的数据?我错过了什么吗?我怎样才能让它通过发送值,因为这在前端可以完美地发送调用并将结果加载到预期的字段中,但是在提交表单时似乎无法访问其中设置的值ajax 调用。
如果你很好奇,网络应用程序另一部分的工作部分也在这里:
ajax 调用:https://dpaste.com/385NDRJPD
处理程序:https://dpaste.com/27UZA9EA6
路线:https://dpaste.com/49579JGP3
显然,这个工作示例是一个更简单的路由,它只处理向数据库添加数据的单个表单,而我遇到问题的路由更大并且处理更多操作。
我一直在搜索并遇到了这个: Post values from an HTML form and access them in a Flask view
但事实并非如此,因为我的表单显示宏呈现的 HTML 是:
<dt> <label class="lesson" for="lesson">Class</label></dt>
<dd><select class="form-control lesson_name" id="lesson_name" name="lesson" style="width:33%;"><option value="6">STA - 1 Students: 1/8 14:00:00</option></select>
</dd>
<br>
【问题讨论】:
标签: python jquery ajax flask flask-wtforms