Wring file retrieved using Blobstore
I have form upload and handler which allows download uploaded files from blobstore. The problem is when I click Download button of any related-field it downloads the same file every time. I.e. I've uploaded 3 files (1.txt, 2.txt, 3.txt) and it always downloads only 1.txt whenever I clicked another Download buttons. You can see it at http://my77notes.appspot.com/show (or http://my77notes.appspot.com/upload first for uploading your own files). When I've researched source code it shows me different keys for every hidden fields.. What did I wrong?
Here is my files:
template file:
<h2>Files uploaded to Blobstore</h2>
<table border="3">
<tr>
<td>#</td>
<td>Filename</td>
<td>Content-Type</td>
<td>Creation</td>
<td>Size</td>
<td>Download</td>
</tr>
<form id="show_blob" name="show_blob" method="post" action="{{ download_blob }}">
{% for file in blob_files %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ file.filename }}</td>
<td>{{ file.content_type }}</td>
<td>{{ file.creation }}</td>
<td>{{ file.size }}</td>
<td>
<input type="submit" name="download" value="Download"/>
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</td>
</tr>
{% endfor %}
</form>
</table>
handl开发者_如何学Goer.py
class BlobstoreServeHandler(RequestHandler, BlobstoreDownloadMixin):
def post(self):
blob_info = blobstore.BlobInfo.get(self.request.form.get('blobkey'))
return self.send_blob(blob_info, save_as=True)
urls.py
rules = [
Rule('/', endpoint='index', handler='apps.77notes.handlers.IndexPageHandler'),
Rule('/upload', endpoint='upload/html', handler = 'apps.77notes.handlers.BlobstoreUploadFormHandler'),
Rule('/upload/handler', endpoint='upload/handler', handler='apps.77notes.handlers.UploadHandler'),
Rule('/download', endpoint='download/html', handler = 'apps.77notes.handlers.BlobstoreDownloadFormHandler'),
Rule('/download/file', endpoint='download/file', handler='apps.77notes.handlers.BlobstoreServeHandler'),
Rule('/show', endpoint='show/html', handler='apps.77notes.handlers.ShowUploadedFilesHandler'),
]
variables
blob_files = uploaded_files_to_blobstore = blobstore.BlobInfo.all()
download_blob = self.url_for('download/file')
Thanks!
Of course it's always the first. You're declaring three hidden fields with the same name but various values. How could the server understand you want “the hidden field nearest to the download button I clicked”?
You could do this with Javascript but it's overkill. Maybe you should rather create forms for each item, but I'm not sure it is HTML-valid.
{% for file in blob_files %}
<tr>
<!-- stuff -->
<td><form class="show_blob" name="show_blob" method="post" action="{{ download_blob }}">
<input type="submit" name="download" value="Download" />
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</form></td>
</tr>
{% endfor %}
If you don't like this, you could also provide the index of the desired blobkey within the download submit button. Something like this:
{% for file in blob_files %}
<tr>
<!-- stuff -->
<td>
<input type="submit" name="dl{{ loop.counter0 }}" value="Download" />
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</td>
</tr>
{% endfor %}
Then, server-side, you get the right blobkey using:
# don't forget to handle errors here, NTUI
ind = int([_[2:] for _ in self.request.form if _.startswith('dl')][0])
blobkeys = self.request.form.getlist('blobkey')
blobkey = blobkeys[ind]
# stuff
if you what to download through form you need to do as many form as blob you have
{% for file in blob_files %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ file.filename }}</td>
<td>{{ file.content_type }}</td>
<td>{{ file.creation }}</td>
<td>{{ file.size }}</td>
<td>
<form id="show_blob" name="show_blob" method="post" action="{{ download_blob }}">
<input type="submit" name="download" value="Download"/>
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</form>
</td>
</tr>
{% endfor %}
or you can do it by ordinary A tag like this <a href = '/get/{{ file.key() }}'>
精彩评论