2014-12-04 54 views
0

我使用BlobStore創建了Dropbox服務,但是我找不到從我的Django HTML模板實現文件下載選項的好方法。Blobstore Python API使用Django HTML模板下載URL

這裏是我的app.yaml

application: my_application 
version: 1 
runtime: python27 
api_version: 1 
threadsafe: false 

handlers: 
- url: /favicon\.ico 
    static_files: favicon.ico 
    upload: /favicon\.ico 

- url: (/.*)* 
    script: main.app 

libraries: 
- name: django 
    version: latest 

這裏是main.py

#!/usr/bin/env python 
from django.core.management import setup_environ 
import os 
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' 

from google.appengine.api import users 
from google.appengine.ext import db 
from google.appengine.ext import webapp 
from google.appengine.ext import blobstore 
from google.appengine.ext.blobstore import BlobInfo 
from google.appengine.ext.webapp import blobstore_handlers 
from google.appengine.ext.webapp.util import run_wsgi_app 
from google.appengine.ext.webapp import template 
from google.appengine.ext.webapp import util 
import django 
import webapp2 
import wsgiref.handlers 

class UserUpload(db.Model): 
    blob_key =  blobstore.BlobReferenceProperty(required=True) 
    user =   db.UserProperty(required=True) 
    user_id =  db.StringProperty(required=True) 
    creation =  db.DateTimeProperty(required=True, auto_now_add=True) 
    filename =  db.StringProperty() 
    content_type = db.StringProperty() 
    size =   db.IntegerProperty() 
    MD5 =   db.StringProperty() 

# Start Dumpbox login 
class MainPage(webapp2.RequestHandler): 
    @util.login_required 
    def get(self): 
     logout_url = users.create_logout_url('/') 
     upload_url = blobstore.create_upload_url('/upload') 
     user = users.get_current_user() 
     q = UserUpload.all() 
     q.filter('user_id =', users.get_current_user().user_id()) 
     q.order('-creation') 
     if user: 
      html = template.render('templates/header.html', {'title': 'Dumpbox', 'nickname': user.nickname(), 'url': upload_url}) 
      html = html + template.render('templates/table.html', { 'file_name': 'File Name', 
                    'content_type': 'Content Type', 
                    'size': 'Size', 
                    'timestamp': 'Creation Date', 
                    'q': q 
                    }) 
      html = html + template.render('templates/footer.html', {'logout_link': logout_url}) 
      self.response.out.write(html) 
     else: 
      self.redirect(users.create_login_url(self.request.uri)) 

class LogoutHandler(webapp2.RequestHandler): 
    def get(self): 
     self.auth.unset_session() 
     self.redirect(self.uri_for('home')) 

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler): 
    def post(self): 
     upload_files = self.get_uploads('file') # 'file' is file upload field in the form 
     blob_info = upload_files[0] 
     user_upload = UserUpload( user=users.get_current_user(), 
            user_id=users.get_current_user().user_id(), 
            blob_key=blob_info.key(), 
            filename=blob_info.filename, 
            content_type=blob_info.content_type, 
            size=blob_info.size, 
            creation=blob_info.creation, 
            MD5=blob_info.md5_hash 
            ) 
     db.put(user_upload) 
     self.redirect('/') 

class DownloadHandler(blobstore_handlers.BlobstoreDownloadHandler): 
    def get(self, resource): 
     resource = str(urllib.unquote(resource)) 
     blob_info = blobstore.BlobInfo.get(resource) 
     self.send_blob(blob_info) 

app = webapp2.WSGIApplication([('/', MainPage),('/upload', UploadHandler),('/download([^/]+)?', DownloadHandler)],debug=True) 
wsgiref.handlers.CGIHandler().run(app) 

def main(): 
    run_wsgi_app(app) 

if __name__ == '__main__': 
    main() 

Django的模板使用一個表有一個複選框選擇要下載的文件,但我可以」找到一個實現它的好方法。

如何勾選複選框並提交表單以下載blobstore文件?

<form method="GET" action=""> 
    <div id="table-wrapper"> 
     <div id="table-scroll"> 
      <table id="file_table" class="display" style="width:100%"> 
       <tr> 
       <th style="width:10px"><input type="checkbox" onclick="checkAll(this)"/></th> 
       <th>{{file_name}}</th> 
       <th>{{content_type}}</th>  
       <th>{{size}}</th>  
       <th>{{timestamp}}</th> 
       </tr> 
       {% for file in q %} 
       {% if file.size > 0 %} 
       <tr> 
        <td><input id="{{file.blob_key}}" type="checkbox"/></td> 
        <td><a href="/{{file.blob_key}}/download">{{file.filename}}</a></td> 
        <td>{{file.content_type}}</td> 
        <td>{{file.size}} Bytes</td> 
        <td>{{file.creation}}</td> 
       </tr> 
       {% endif %} 
       {% endfor %} 
      </table> 
     </div> 
    </div> 
    <p><input type="submit" value="Download"></p> 
</form> 

感謝任何幫助。

回答

0

這裏是我的解決方案:
在模板變化

<td><a href="/{{file.blob_key}}/download">{{file.filename}}</a></td> 

行成

<td><a href="/download?key={{file.blob_key}}">{{file.filename}}</a></td> 

在你的意見添加了兩個方法:

def download(request,client): 
    if 'key' in request.GET: 
     blob_key_str = request.GET['key'] 
    if not blob_key_str: 
     return HttpResponseRedirect(request.META.get('HTTP_REFERER')) 

    blob_key = str(urllib.unquote(blob_key_str)) 
    blob = blobstore.BlobInfo.get(blob_key) 

    try: 
     return send_blob(blob, save_as=True) 
    except ValueError, error: 
     return HttpResponseRedirect(request.META.get('HTTP_REFERER')) 

import cgi 
import logging 
import urllib 
def send_blob(blob_key_or_info, content_type=None, save_as=None): 

    CONTENT_DISPOSITION_FORMAT = 'attachment; filename="%s"' 
    if isinstance(blob_key_or_info, blobstore.BlobInfo): 
     blob_key = blob_key_or_info.key() 
     blob_info = blob_key_or_info 
    else: 
     blob_key = blob_key_or_info 
     blob_info = None 

    logging.debug(blob_info) 
    response = HttpResponse() 
    response[blobstore.BLOB_KEY_HEADER] = str(blob_key) 

    if content_type: 
     if isinstance(content_type, unicode): 
     content_type = content_type.encode('utf-8') 
     response['Content-Type'] = content_type 
     else: 
     del response['Content-Type'] 

    def send_attachment(filename): 
     if isinstance(filename, unicode): 
     filename = filename.encode('utf-8') 
     response['Content-Disposition'] = (CONTENT_DISPOSITION_FORMAT % filename) 

    if save_as: 
     if isinstance(save_as, basestring): 
     send_attachment(save_as) 
     elif blob_info and save_as is True: 
     send_attachment(blob_info.filename) 
     else: 
     if not blob_info: 
      raise ValueError('The specified file is not found.') 
     else: 
      raise ValueError(
       'Unexpected value for the name in which file is ' 
       'expected to be downloaded') 

    return response 

根據您的需要更改此代碼:)