Вопрос

I keep getting this error and I can't figure out what the problem is -- specifically, why the form is not validating on submit. All my other forms work fine. Any help is appreciated.

Error:
2014-02-28 15:21:26,581 :Exception on /add_item [POST]
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1687, in wsgi_app
    response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1361, in full_dispatch_request
response = self.make_response(rv)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1439, in make_response
raise ValueError('View function did not return a response')
ValueError: View function did not return a response

Here is my model.py:

class Track(db.Model):
    __tablename__ = 'track'
    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.Date)
    station_start = db.Column(db.Float)
    station_end = db.Column(db.Float)
    quantity = db.Column(db.Float)
    img = db.Column(db.String(200))
    caption = db.Column(db.String(600))
    area_id = db.Column(db.Integer, db.ForeignKey('area.id'))
    location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
    shift_id = db.Column(db.Integer, db.ForeignKey('shift.id'))
    material_id = db.Column(db.Integer, db.ForeignKey('material.id'))

    def __init__(self, date, station_start, station_end, quantity, img, caption):
        self.date = date
        self.station_start = station_start
        self.station_end = station_end
        self.quantity = quantity
        self.img = img
        self.caption = caption

    def get_id(self):
        return unicode(self.id)

The form definition from forms.py:

class TrackingForm(Form):
    date = DateField('Date (MM/DD/YYYY)', validators=[Required()], format='%m/%d/%Y')
    station_start = FloatField('Starting Station (XX.XX)')
    station_end = FloatField('Ending Station (XX.XX)')
    quantity = FloatField('Quantity')
    img = FileField('Image')
    caption = TextAreaField('Description')
    area = QuerySelectField(query_factory=getAllAreas, get_label='area')
    location = QuerySelectField(query_factory=getAllLocations, get_label='location')
    shift = QuerySelectField(query_factory=getAllShifts, get_label='shift')
    material = QuerySelectField(query_factory=getAllMaterials, get_label='material')

My views.py:

@app.route("/add_item", methods=["POST"])
@login_required
def add_item():
    form = TrackingForm()
    if form.validate_on_submit():
        img_file = form.img.data
        if img_file and allowed_file(img_file.filename):
            img_filename = secure_filename(str(uuid.uuid4()) + img_file.filename)
            img_file.save(os.path.join(app.config['UPLOAD_FOLDER'], img_filename))
        else:
            img_filename = ""

        t = Track(date = form.date.data,
        station_start = form.station_start.data,
        station_end = form.station_end.data,
        quantity = form.quanitity.data,
        img = img_filename,
        caption = form.caption.data)

        db.session.add(t)
        db.session.commit()

        form_location = form.location.data
        l = Location.query.filter_by(location = form_location.location).first()
        l.tracks.append(t)
        db.session.commit()

        form_area = form.area.data
        a = Area.query.filter(Area.area == form_area.area).first()
        a.tracks.append(t)
        db.session.commit()

        form_material = form.material.data
        m = Material.query.filter_by(material = form_material.material).first()
        m.tracks.append(t)
        db.session.commit()

        return redirect(url_for('daily_report'))
    return redirect(url_for('daily_report'))

And the HTML:

<div class="modal fade" id="add_item_form">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            <h4 class="modal-title">Add to Report</h4>
        </div>
        <div class="modal-body">
            <div class="container">
            <div class="col-lg-3">
            <form action="/add_item" method="POST" enctype="multipart/form-data" class="form-default">
            {{ form.hidden_tag() }}
            {% call macro.form_field(form.date) %} {% endcall %}
            <div class="input-group input-group">
            <span class="input-group-addon">Area</span>
            {% call macro.form_field(form.area) %} {% endcall %}
            {% call macro.form_field(form.location) %} {% endcall %}
            </div>
            <p>
            <div class="input-group input-group">
            <span class="input-group-addon">Material: </span>
            {% call macro.form_field(form.material) %} {% endcall %}
            </div>
            </p>
            {% call macro.form_field(form.station_start) %} {% endcall %}
            {% call macro.form_field(form.station_end) %} {% endcall %}
            {% call macro.form_field(form.quantity) %} {% endcall %}
            {% call macro.form_field(form.img) %} {% endcall %}
            {% call macro.form_field(form.caption) %} {% endcall %}
            <input type="submit" value="Submit" class="btn btn-primary">
            </form>
            </div>
            </div>
        </div>
    </div>
</div>
</div>
Это было полезно?

Решение

if form.validate_on_submit():

If this if statement fails None is returned.

Add a fallthrough at the end like so return abort(400)

Другие советы

The traceback points to the view function. At first glace it looks like your form processing is a mess and your not returning any values. I think your best bet is to look at a working example and compare it with what you wrote.

Here is a an example of how render a blank form and processes a submit in a single view.

@app.route('/create', methods=['GET', 'POST'])
@login_required
def create_post():
    form = PostForm()
    if form.validate_on_submit():
        aid = current_user.id
        url = slugify(form.title.data)
        tags = tagify(form.tags.data)
        post = Post(title=form.title.data, author_id=aid, url=url, pub_date=form.pub_date.data, body=form.body.data, topic=form.topic.data, tags=tags)
        db.session.add(post)
        db.session.commit()
        Topic.update_counts()
        flash('Your post has been published.')
        return redirect(url_for('display_post', url=url))
    posts = Post.query.all()
    return render_template('create_post.html', form=form, posts=posts)

how it works...

  1. If no post, renders an empty form for the user to fill out.
  2. If user submit, adds and commits the db session and redirects the user.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top