验证Flask表单并同时传递JavaScript数组

时间:2017-11-04 16:30:29

标签: javascript python ajax flask

如何在同一视图中同时传递JavaScript值并验证表单?由于您只能将一个值“X”传递给$.ajax({data: X}),现在我知道我可以将字典传递给data:,但这不会评估$('form').serialize()。现在我有$.ajax({})来处理表单验证和$.post()来传递javascript数组到Flask视图。验证是True但是jsArray从未提交过!我错过了什么?

的index.html

{% from '_formhelpers.html' import render_field %}
<form>
  {{ form.hidden_tag() }}
  {{ render_field(form.first_name)}}
  {{ render_field(form.last_name) }}
  <button id='submit-btn'>submit</button>
</form>
<script>
  var jsArray = JSON.stringify([{'item1': 'value1'}, {'item2': 'value2'}]);
  $('#submit-btn').click(function(event) {

    $.post(url: '/', data:jsArray, mimetype: 'application/json', success: function(){alert('data post success')});
    $.ajax({
      type: 'POST',
      url: '/',
      data: $('form').serialize(),
      success: function(data) {
        window.location.replace('/success');
      }
    });
    event.preventDefault();
  });
</script>

test.py

from flask import Flask, render_template, request, url_for
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired


app = Flask(__name__)
app.secret_key = 'mysecretkey'


class MyForm(FlaskForm):
    first_name = StringField('first name', validators=[DataRequired('please enter your name')])
    lasthttps://stackoverflow.com/_name = StringField('last name', validators=[DataRequired()])


@app.route('/', methods=['POST', 'GET'])
def index():
    form = MyForm(request.form)
    if request.method == 'POST' and form.validate():
        data = request.get_json()
        print(data) # >>> None
        # i am handling the return in the AJAX success function.
    return render_template('index.html', form=form)

@app.route('/success')
def success():
    return 'success!'

_formhelpers.html

{% macro render_field(field) %}
  <dt>{{ field.label }}
  <dd>{{ field(**kwargs)|safe }}
  {% if field.errors %}
    <ul class='error'>
      {% for error in field.errors %}
        <li>{{ error }}</li>
      {% endfor %}
    </ul>
  {% endif %}
  </dd>
{% endmacro %}

1 个答案:

答案 0 :(得分:0)

这是一个有效的例子,希望确实是你想要的。

test.py

from flask import render_template, Flask, jsonify
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired

app = Flask(__name__)
app.secret_key = 'example'

class MyForm(FlaskForm):
    first_name = StringField('first name', validators=[DataRequired('please enter your name')])
    last_name = StringField('last name', validators=[DataRequired()])

@app.route('/')
def home():
    form = MyForm()
    return render_template('example.html', form=form)

@app.route('/something/', methods=['post'])
def something():
    form = MyForm()
    if form.validate_on_submit():
        return jsonify(data={'message': 'hello {}'.format(form.first_name.data)})
    return jsonify(data=form.errors)

if __name__ == '__main__':
    app.run(debug=True)

example.html的

{% from '_formhelpers.html' import render_field %}
<!DOCTYPE html>
<html>
    <head>
        <title>Example Post AJAX Out get JSON Back</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
        <script>
         $(document).ready(function() {
             $('form').submit(function (e) {
                 var url = "{{ url_for('something') }}"; // send the form data here.
                 $.ajax({
                     type: "POST",
                     url: url,
                     data: $('form').serialize(), // serializes the form's elements.
                     success: function (data) {
                         console.log(data)  // display the returned data in the console.
                     }
                 });
                 e.preventDefault(); // block the traditional submission of the form.
             }); 
             // Inject our CSRF token into our AJAX request.
             $.ajaxSetup({
                 beforeSend: function(xhr, settings) {
                     if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                         xhr.setRequestHeader("X-CSRFToken", "{{ form.csrf_token._value() }}")
                     }
                 }
             })
         });
        </script>
    </head>

    <body>
        <form id="foo">
            {{ form.hidden_tag() }}
            {{ render_field(form.first_name)}}
            {{ render_field(form.last_name) }}
            <input type="submit" value="Submit"/>
        </form>
    </body>
</html>

如果验证失败,我们会发回整个form.errors字典。