首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >烧瓶WTForms:为什么我的帖子要求上传一个文件而不发送文件数据?

烧瓶WTForms:为什么我的帖子要求上传一个文件而不发送文件数据?
EN

Stack Overflow用户
提问于 2018-10-19 19:53:45
回答 2查看 2.6K关注 0票数 4

我正在尝试制作一个表单来上传一个文件,但是文件数据并没有随请求一起发送。我正在手动导航到我的文件并点击提交。我的FileRequired验证器失败了。(如果不包括它,form.scan_file上的form.scan_file字段是空的。)

这是我的表格:

代码语言:javascript
复制
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed, FileRequired

class ScanForm(FlaskForm):
    scan_file = FileField(validators=[FileAllowed(['nii', 'nii.gz', 'zip']), FileRequired()])

这是我的views.py

代码语言:javascript
复制
from flask import Blueprint, render_template, request, flash, redirect, url_for, session
from .models import Scan
from .forms import ScanForm
from .service import ScanService
from cookiecutter_mbam.utils import flash_errors

blueprint = Blueprint('scan', __name__, url_prefix='/scans', static_folder='../static')

@blueprint.route('/add', methods=['GET', 'POST'])
def add():
    """Add a scan."""
    form = ScanForm(request.form)
    if form.validate_on_submit():
        f = form.scan_file.data
        service = ScanService()
        xnat_uri = service.upload(session['user_id'], session['curr_experiment'], f)
        Scan.create(xnat_uri=xnat_uri)
        flash('You successfully added a new scan.', 'success')
        return redirect(url_for('experiment.experiments'))
    else:
        flash_errors(form)
    return render_template('scans/upload.html',scan_form=form)

这是我的upload.html

代码语言:javascript
复制
{% extends "layout.html" %}

{% block content %}


<form method="POST" action="{{ url_for('scan.add') }}" enctype="multipart/form-data">
    {{ scan_form.csrf_token }}

    <input type="file" name="file">
    <input class="btn btn-primary" type="submit" value="Submit">

</form>

{% endblock %}

看起来我并没有像这个人那样犯同样的错误。我做错了什么?

编辑:自从发帖以来,我已经找到了这个问题,但在研究所提供的解决方案时,似乎与我的情况无关。

编辑2:有一次,我在Werkzeug调试器中打印了request.files,它是一个空的数据集。我无法准确地重建我为得到这个结果所做的一切。从那以后,我插入了一些print语句,实际上,request.files有我的file对象。所以我有办法取回我的文件。但是我应该能够在form.scan_file.data检索我的文件对象(参见这里)。现在,它的计算结果为None。更具体地说,form.scan_file.has_file()的计算结果为Falseform.data计算为{'scan_file': None, 'csrf_token': <long-random-string> }

即使我有另一种方法来检索我的文件对象,这个问题的一个结果就是验证不起作用。我的表单没有通过FileRequired()验证。

编辑3:通过我对问题的新理解,我发现它类似于这个问题。但是,这显然不是重复的,因为form = ScanForm(request.form)form = ScanForm()form = ScanForm(CombinedMultiDict((request.files, request.form)))对编辑2中概述的行为没有任何影响。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-20 15:20:20

首先,检查您的数据是否在该路径上发布。其次,我认为您不需要将request.form传递给ScanForm,只需要实例化它:

代码语言:javascript
复制
def add():
    """Add a scan."""
    form = ScanForm()
    ...

检查用表单发布的内容,而不是

代码语言:javascript
复制
if form.validate_on_submit():

您可以使用,并打印form.scan_file.data

代码语言:javascript
复制
if form.is_submitted():
    print(form.scan_file.data)

最后,可以使用{scan_form.scan_file}<input type="file" name="scan_file"> (输入元素的名称属性应为"scan_file")呈现输入文件。

以下是我的例子:

表格:

代码语言:javascript
复制
class ArticleForm(FlaskForm):
    article_image = FileField('Article_image', validators=[FileRequired()])

表格模板:

代码语言:javascript
复制
<form action="" method="post" enctype="multipart/form-data">
    {{ article_form.csrf_token }}
    {{ article_form.article_image }}
    <input type="submit" value="submit"/>
</form>

控制器(保存文件):

代码语言:javascript
复制
article_form = ArticleForm()

        if article_form.validate_on_submit():

            f = article_form.article_image.data
            name = current_user.username + "__" + f.filename
            name = secure_filename(name)
            f.save(os.path.join("./static/article_images/", name))
票数 6
EN

Stack Overflow用户

发布于 2022-08-24 17:34:29

我愚蠢到忘记将enctype="multipart/form-data"添加到form标记中,这导致form.file.data只包含文件的名称,而不是整个生命。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52899084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档