如何使用单个 multipartform post header 键上传可变数量的文件
How to upload a variable amount of files using a single multipartform post header key
我有一个可重复的表单域:
<div class="repeat">
<input type="file" name="files[==row-count-placeholder==]" />
</div>
这将(使用 jQuery)例如导致
<div class="repeat">
<input type="file" name="files[0]" />
<input type="file" name="files[1]" />
<input type="file" name="files[2]" />
<!-- and so on -->
</div>
根据用户要上传的文件数量。表单方法是 post
并且 enctype 是 multipart/form-data
.
使用 cherrypy 作为我的服务器和华丽的验证库我想保存上传的文件:
import voluptuous
def save_uploaded_file(file, path)
#save file on server...
def validate_files(files):
for file in files:
save_uploaded_file(file, cherrypy.request.config['static_dir'])
@cherrypy.expose
def index(self, **kwargs):
schema = Schema({
'files' : validate_files
}, required = True, extra = True)
kwargs = schema(kwargs)
因此,根据一个键[,我实际上需要一个包含所有文件信息的 post header(最好是文件列表之类的东西) 调用了 files
,但我得到的只是多个键,例如 files[0]
、files[1]
等等...
我该如何处理?我是否必须以某种方式手动创建一个包含所有 files
信息的数组,或者是否有更常见或更实用的方法来做到这一点?
解决方案(按照saaj的建议):
schema_dict = {
'name' : All(Length(min=3, msg="Can't believe that there is a name less than 3 characters...")),
# ...
}
# validate files
isPart = lambda v: isinstance(v, cherrypy._cpreqbody.Part)
files1 = [a for a in kwargs.values() if isPart(a)]
files2 = [a for a in cherrypy.request.params.values() if isPart(a)]
assert files1 == files2
for file in files1:
# for each file add dict entry and route to validation function
schema_dict.update({file.name : validate_file})
schema = volu.Schema(schema_dict, required = True, extra = True)
像这样一个 Schema
显然可以包含许多其他字段。提交的文件一般添加到任何 Schema
。酷!
只需从请求中获取文件部分(如果您的表单不包含其他类型的部分,您可以按原样获取请求的参数)。
@cherrypy.expose
def index(self, **kwargs):
isPart = lambda v: isinstance(v, cherrypy._cpreqbody.Part)
files1 = [a for a in kwargs.values() if isPart(a)]
files2 = [a for a in cherrypy.request.params.values() if isPart(a)]
assert files1 == files2
print(files1) # pass it where you want to
CherryPy 相关问题:upload performance, asynchronous upload。
我有一个可重复的表单域:
<div class="repeat">
<input type="file" name="files[==row-count-placeholder==]" />
</div>
这将(使用 jQuery)例如导致
<div class="repeat">
<input type="file" name="files[0]" />
<input type="file" name="files[1]" />
<input type="file" name="files[2]" />
<!-- and so on -->
</div>
根据用户要上传的文件数量。表单方法是 post
并且 enctype 是 multipart/form-data
.
使用 cherrypy 作为我的服务器和华丽的验证库我想保存上传的文件:
import voluptuous
def save_uploaded_file(file, path)
#save file on server...
def validate_files(files):
for file in files:
save_uploaded_file(file, cherrypy.request.config['static_dir'])
@cherrypy.expose
def index(self, **kwargs):
schema = Schema({
'files' : validate_files
}, required = True, extra = True)
kwargs = schema(kwargs)
因此,根据一个键[,我实际上需要一个包含所有文件信息的 post header(最好是文件列表之类的东西) 调用了 files
,但我得到的只是多个键,例如 files[0]
、files[1]
等等...
我该如何处理?我是否必须以某种方式手动创建一个包含所有 files
信息的数组,或者是否有更常见或更实用的方法来做到这一点?
解决方案(按照saaj的建议):
schema_dict = {
'name' : All(Length(min=3, msg="Can't believe that there is a name less than 3 characters...")),
# ...
}
# validate files
isPart = lambda v: isinstance(v, cherrypy._cpreqbody.Part)
files1 = [a for a in kwargs.values() if isPart(a)]
files2 = [a for a in cherrypy.request.params.values() if isPart(a)]
assert files1 == files2
for file in files1:
# for each file add dict entry and route to validation function
schema_dict.update({file.name : validate_file})
schema = volu.Schema(schema_dict, required = True, extra = True)
像这样一个 Schema
显然可以包含许多其他字段。提交的文件一般添加到任何 Schema
。酷!
只需从请求中获取文件部分(如果您的表单不包含其他类型的部分,您可以按原样获取请求的参数)。
@cherrypy.expose
def index(self, **kwargs):
isPart = lambda v: isinstance(v, cherrypy._cpreqbody.Part)
files1 = [a for a in kwargs.values() if isPart(a)]
files2 = [a for a in cherrypy.request.params.values() if isPart(a)]
assert files1 == files2
print(files1) # pass it where you want to
CherryPy 相关问题:upload performance, asynchronous upload。