海报发布表单与未选择的文件输入字段

时间:2017-12-14 15:51:34

标签: python python-2.7

我有一个包含大量文本输入字段的表单,以及用户CV的文件输入字段:

rf.interpolate()

   Week  Rainfall(cm)
0     1           1.0
1     2           5.0
2     3           9.0
3     4          10.0
4     5          11.0
5     6          12.0
6     7          13.0
7     8          14.0

此字段不是必填字段,因此每当用户在未选择文件的情况下发布表单时,服务器端逻辑将不会删除存储在数据库中的任何先前上载的CV。

我注意到,当我没有使用浏览器选择文件并发布表单时,POST请求的有效负载如下所示:

<input id="cv" name="cv" accept="application/pdf" type="file" value=""/>

我现在正在使用poster模块对我的应用程序进行压力测试。我使用海报使用标准的multipart / form-data编码提交帖子。我或多或少地使用它:

------WebKitFormBoundaryaxaKZBvja5RsdU6h
Content-Disposition: form-data; name="lastName"

Smith
------WebKitFormBoundaryaxaKZBvja5RsdU6h
Content-Disposition: form-data; name="cv"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundaryaxaKZBvja5RsdU6h
Content-Disposition: form-data; name="country"

USA

上述作品并张贴表格,包括简历。我现在想要实现的是使用海报模块发布表单,而不提供简历并创建与以前完全相同的POST负载。

我试过了:

opener = register_openers()
fields = {'lastName': 'Smith', 'cv': open('cv.pdf'), 'country': 'USA'}
datagen, headers = multipart_encode(fields)
request = urllib2.Request('account-submit', datagen, headers)
result = opener.open(request)

......以及许多变体,例如:

fields = {'lastName': 'Smith', 'cv': open(''), 'country': 'USA'}

......但它们似乎都没有用。唯一可行的是完全省略'cv'字段,虽然我可以让它工作,但它需要更改我的服务器端逻辑,因为后者期望未被“填充”的CV字段的请求有效负载准确如上所示,即:

'cv': open(None)
'cv': open(None)
'cv': open([])
'cv': None

如何使用海报模块实现这一目标?

1 个答案:

答案 0 :(得分:1)

Poster将根据可用属性解释提供的对象。您可以在此处查看将对象类型化为文件的逻辑的源代码:

https://bitbucket.org/chrisatlee/poster/src/97d3c6fcb87785d1838549301f0092dec4229abf/poster/encode.py?at=default&fileviewer=file-view-default#encode.py-173

正如您所看到的,它正在寻找具有read方法的东西。如果是这样,它会将其视为文件并使用您尝试实现的八位字节流编码。

以下是获取清空文件的两种简单方法。 这个是最干净的,因为它不依赖于os /文件系统。

import StringIO
...
my_empty_file = StringIO.StringIO()
fields = {'lastName': 'Smith', 'cv': my_empty_file, 'country': 'USA'}

如果这不起作用(很难确定它没有测试),你可以传递一个实际的空文件:

fields = {'lastName': 'Smith', 'cv': open('/dev/null'), 'country': 'USA'}