linrong / flask-server

this is a project for wx server
MIT License
0 stars 0 forks source link

file文件传输问题 #1

Closed linrong closed 5 years ago

linrong commented 5 years ago

目前

目前版本 ae64d930eb16f50debd681746c3c73cbf0265245 之前的使用文件上传模块是有问题的。 在file.py中:

def upload_file():
    '''文件上传'''
    form = UploadPDFValidator().validate_for_api()
    origin_file = request.files[form.origin.name]
    origin_file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], origin_file.filename))
    comparer_file = request.files[form.comparer.name]
    comparer_file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], comparer_file.filename))
    return RenewSuccess()

form.py中:

class UploadPDFValidator(BaseValidator):
    origin = FileField(validators=[DataRequired()])
    comparer = FileField(validators=[DataRequired()])     

base.py中

class BaseValidator(Form):
    def __init__(self):
        # 这里接收了request携带的数据,然后用于检验
        data = request.get_json(silent=True) # body中
        view_args = _request_ctx_stack.top.request.view_args # 获取view中(path路径里)的args
        args = dict(request.args.to_dict(), **view_args) # query中: request.args.to_dict()
        super(BaseValidator, self).__init__(data=data, **args)

    def validate_for_api(self):
        # validate方法会对我们的所有字段进行迭代并且调用行内验证方法进行验证, 遇到validate_xxx继续调用行内验证方法验证, 具体关于wtforms的validate方法参考wtforms validate解释.
        # http://greyli.com/how-custom-validator-work-in-wtforms/
        # 调用BaseValidator父类的validate方法
        valid = super(BaseValidator, self).validate()
        if not valid:
            # 验证错误处理,抛出错误,self.errors即为validate_xx中抛出的错误
            raise Param
linrong commented 5 years ago

使用的调试方法为使用postman,通过post方法发送数据到 http://127.0.0.1:8010/cms/file/upload 进行测试,其中设置Header: Content-Type:multipart/form-data,在Body中携带参数form-data分别为origin:xx文件comparer:xx文件

linrong commented 5 years ago

目前使用的是继承wtforms的BaseValidator表单验证: 在file.py中调用form = UploadPDFValidator().validate_for_api()进行表单验证,然后使用form.origin.name获取文件对应的键值名称从request.files中获取文件数据,然后对文件数据进行保存。 测试发现: 测试结果报错,提示在form.py中定义的两个应该上传的文件属性都为缺失的 在file.py中断点可知form.origin.name能够获取到,并且form.origin.data=None

但是如果在file.py中修改form = UploadPDFValidator().validate_for_api()form = UploadPDFValidator(),文件会正常报错并没报错,因为没有调用统一最后处理验证的函数validate_for_api,关于这个可以自己在form中为UploadPDFValidator写好验证判断,不使用统一的

linrong commented 5 years ago

使用的是wtforms的: 即:

class UploadPDFValidator(wtforms.Form):
    origin = FileField(validators=[DataRequired()])
    comparer = FileField(validators=[DataRequired()]) 
def upload_file():
    '''文件上传'''
    form = UploadPDFValidator()

这时候测试结果没有报错,文件可以上传到文件夹,在file.py中断点可知form.origin.name能够获取到,并且form.origin.data=None 没有报错应该是因为在form中的UploadPDFValidator处没有写验证判断,所以不会报错

linrong commented 5 years ago

使用的是from flask_wtf import FlaskForm的: 即:

class UploadPDFValidator(FlaskForm):
    origin = FileField(validators=[DataRequired()])
    comparer = FileField(validators=[DataRequired()]) 
def upload_file():
    '''文件上传'''
    form = UploadPDFValidator()

这时候测试结果没有报错,文件可以上传到文件夹,在file.py中断点可知form.origin.name能够获取到,并且form.origin.data能够获取到文件数据的 因为form.origin.data能够获取到文件数据说明文件数据成功赋值到form中,可能这是FlaskForm的不同

linrong commented 5 years ago

安装flask_wtf 的原因是同时安装wtforms

linrong commented 5 years ago

目前更新commit 01e91cbce8d0090c01e9c07431eb9293269cad40 完成对于使用wtforms进行文件检验的代码,主要修改了文件数据的读取和检验