在我的表单中使用 MultipleFileField() 时,FileRequiredValidator() 不起作用

FileRequiredValidator() doesn't work when using MultipleFileField() in my form

我的上传表单class:

    from app import app
    from flask_wtf.file import FileRequired, FileAllowed
    from wtforms.fields import MultipleFileField
    from wtforms.validators import InputRequired,DataRequired
  class UploadForm(FlaskForm):
     .
     .
     .
     roomImage = MultipleFileField('Room',validators=[FileAllowed(['jpg', 'png'], 'Image only!'), FileRequired('File was empty!')] )
     .
     .
     .#there are other fields here which are  not relevant to  the problem at hand

HTML 模板

{% extends "base.html" %}

{% block content %}
 <h1>Upload Your Images</h1>
<form  action="/" enctype="multipart/form-data" method="post"  >
    {{ form.csrf_token }}
    Room<br />
    {{form.roomImage()}}
    .
    .
    . <MORE THINGS THAT I HAVE EDITED OUT>
    {{form.submit()}}
    <br/>
    {% if form.errors %}
      {{ form.errors }}
    {% endif %}
</form>
{% endblock %}

hosts.py 到 运行 验证检查

def upload_image():#NEEDS HEAVY FIXING
    """home page to return the web page to upload documents"""
    form = UploadForm()
    if form.validate_on_submit():

使用 VS 的调试工具,我发现 form.validate_on_submit() 不起作用并且总是验证失败,我在 html 页面上收到此错误。

{'roomImage': ['File was empty!']}

还有另一个 MultipleFileField 控件,其代码几乎完全相同。 当我使用 FileField 上传一个文件时,不会发生此问题。关于这方面的文档非常有限,我只需要继续 。我真的不知道如何解决这个问题。我已经广泛搜索以查找涉及 MultipleFileField 的示例,但他们没有使用任何验证。 Github 上的一个帖子,我再也找不到了,建议使用 OptionalValidator,但这对我来说不是一个选项,甚至没有用。 有人可以建议我解决方案吗?

编辑:

甚至 FileAllowed() 验证程序似乎也不起作用。

方法似乎解决了问题的一部分,它使用了 j-query,直到此时我还不熟悉它。 因此,由于我是网络开发的新手,因此我一直在寻找一种基于 python 的方法。我认为它还不存在。 当我解决多文件上传问题时会更新。 Jsfiddle link

jQuery.validator.setDefaults({
  debug: true,
  success: "valid"
});
$( "#myform" ).validate({
  rules: {
    ":file": {
      required: true,
      accept: "image/*"
    }
  }
});

<form id="myform">
<label for="field">Required, image files only: </label>
<input type="file" class="left" id="field" name="field" multiple>
<br/>
<input type="submit" value="Validate!">
</form>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/jquery.validate.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/additional-methods.min.js"></script>

因为我使用的是 wtforms,所以我尝试了一种叫做验证 class 的方法,并且似乎可以解决问题的内联验证器。

 """
Validation Class for RoomUpload
"""
class MyRoomValidator(object):
    def __init__(self, message=None):
        if not message:
            message = u"You need to upload the images with the category as well"
        self.message = message

    def __call__(self, form, field):
        print(len(form.roomImage.data))
        print((form.roomTypeSelect.data))
        if (not form.roomImage.data and  form.roomTypeSelect.data == -1) or(form.roomImage.data and  form.roomTypeSelect.data == -1) or (not form.roomImage.data and  form.roomTypeSelect.data != -1):#check for all possible combinations
            raise ValidationError(self.message)

class RoomUpload(FlaskForm):
    """
    This is meant for the sub-form for room details upload
    containing the details for room and its subtype

    roomImage:Upload the room image
    roomTypeSelect:The subcategory for room category

    The Form will only be submitted if the images  are uploaded and
    the RoomType will be selected
    """
    def validate_roomTypeSelect(form, field):#Inline Validator to ensure if default choice is not chosen
       print(field.data)
       if field.data == -1:
            raise ValidationError('Need to Select Room Type')
    def validate_roomImage(form,field):
        for roomFile in field.data:
            print(roomFile.filename)
            if  isanImageFile(roomFile.filename) == False: 
                raise ValidationError("Error!!! Not an Image File ")
    roomImage = MultipleFileField(u"Room",validators=[MyRoomValidator(),FileAllowed],id = "roomImage")
    roomTypeSelect= SelectField("Room Type",choices=roomTypes,coerce=int,id="roomTypeSelect")
    roomSubmit = SubmitField("Upload the images  of the room")

这对我有用(在 GitHub "between the lines" 上找到):

multi_file = MultipleFileField("Upload File(s)", validators=[DataRequired()])

但是

FileAllowed(["xml", "jpg"])

被忽略,对我不起作用。

编辑: 不,可悲的是,它 不起作用 ... 它 returns 对于 form.validate()form.validate_on_submit() 是正确的但是当你没有传递任何文件时,通过删除

required=""

来自

<input id="multi_file" multiple="" name="multi_file" required="" type="file">

并提交表单,它仍然评估为 True。

所以问题仍然存在,如上所述...

关于 FileAllowed 验证器,它不起作用,因为 FileAllowed 验证器需要一个 FileStorage 对象,但 MultipleFileField 正在发送一个 Filestorage 对象列表,这就是它不起作用的原因。您必须自己实现一个 MultiFileAllowed 验证器。更多详情 Whosebug answer explained with example.