【问题标题】:Why is WTForms not sending the selectfield option value on submit?为什么 WTForms 在提交时不发送选择字段选项值?
【发布时间】: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


    【解决方案1】:

    所以解决方案是我试图将不同的表单发送到相同的路由以进行处理,而不使用 ajax 或任何东西,结果我使用表单的 action 属性将其按顺序发送到不同的路由单独处理每个表单

    【讨论】:

      猜你喜欢
      • 2016-07-22
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 2020-06-03
      • 2017-10-28
      • 2016-06-30
      • 2012-12-07
      • 2014-07-21
      相关资源
      最近更新 更多