2011-09-06 44 views
10

Tôi đang sử dụng Google App Engine Blobstore để lưu trữ một loạt loại tệp (PDF, XLS, v.v.) và đang cố gắng tìm cơ chế theo đó tên tệp gốc của tệp được tải lên - như được lưu trữ trong blob_info - có thể được sử dụng để đặt tên cho tệp tải xuống tức là để người dùng thấy 'some_file.pdf' trong hộp thoại lưu thay vì 'very_long_db_key.pdf'.Tên tệp đã tải xuống bằng Google App Engine Blobstore

Tôi không thể nhìn thấy bất cứ điều gì trong tài liệu mà sẽ cho phép này:

http://code.google.com/appengine/docs/python/blobstore/overview.html

Tôi đã nhìn thấy gợi ý trong bài viết khác mà bạn có thể sử dụng thông tin trong blob_info để đặt tiêu đề Content-Disposition . Đây có phải là cách tiếp cận tốt nhất để đạt được kết quả mong muốn không?

Trả lời

11

Có một tham số 'save_as' tùy chọn trong hàm send_blob. Theo mặc định, giá trị này được đặt thành Sai. Đặt nó thành True sẽ khiến tệp được coi là tệp đính kèm (nghĩa là tệp sẽ kích hoạt hộp thoại tải xuống 'Lưu/Mở') và người dùng sẽ thấy tên tệp thích hợp.

Ví dụ:

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

Nó cũng có thể ghi đè lên tên tập tin bằng cách đi qua trong một chuỗi:

self.send_blob(blob_info,save_as='my_file.txt') 

Nếu bạn muốn có một số nội dung (chẳng hạn như các file PDF) để mở chứ không phải là giúp bạn tiết kiệm có thể sử dụng content_type để xác định hành vi:

blob_info = blobstore.BlobInfo.get(resource) 
type = blob_info.content_type 
if type == 'application/pdf':  
    self.response.headers['Content-Type'] = type 
    self.send_blob(blob_info,save_as=False) 
else: 
    self.send_blob(blob_info,save_as=True) 
+0

Chỉ cần thêm - nếu tên tệp gốc chứa dấu ngoặc kép, hộp thoại tải xuống sẽ cắt ngắn tên tệp sau ký tự trích dẫn. Tôi đã giải quyết vấn đề này bằng cách thoát khỏi các dấu ngoặc kép trong tên tập tin blob: 'self.send_blob (blob_info, save_as = blob_info.filename.thay thế ('"', '\\"')) ' (Có một cuộc thảo luận liên quan về việc này [ở đây] (http://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter -of-content-disposition-header-in-http)) –

0

Có đó là cách tiếp cận tốt nhất; chỉ truy vấn đối tượng BlobInfo bằng cách sử dụng khóa Blobstore đã cho và sử dụng thuộc tính content-type của nó.

1

Để tham khảo trong tương lai, save_as và BlobstoreDownloadHandler được ghi lại ở đây:

http://code.google.com/appengine/docs/python/tools/webapp/blobstorehandlers.html

Nó có vẻ như nó phải là một chút dễ dàng hơn để tìm. Hãy xem nếu nó có thể được cải thiện.

+0

Vâng, tôi đã thấy rằng một khi câu trả lời đã được chỉ ra. send_blob dường như bị thiếu trong tài liệu tham khảo: http://code.google.com/appengine/docs/python/blobstore/overview.html – notreadbyhumans

1

Tùy chọn khác là thêm tên tệp vào cuối URL tải xuống. Ví dụ:

/files/AMIfv95HJJY3F75v3lz2EeyvWIvGKxEcDagKtyDSgQSPWiMnE0C2iYTUxLZlFHs2XxnV_j1jdWmmKbSVwBj6lYT0-G_w5wENIdPKDULHqa8Q3E_uyeY1gFu02Iiw9xm523Rxk3LJnqHf9n8209t4sPEHhwVOKdDF2A/prezents-list.doc 

Nếu bạn sử dụng Jinja2 cho khuôn mẫu, bạn có thể xây dựng một URL như vậy như thế này:

<a href="/files/{{blob_info.key()}}/{{blob_info.filename}}">{{file.filename}}</a> 

thì bạn nên điều chỉnh ánh xạ URL của bạn cho phù hợp với một cái gì đó như thế này:

('/files/([^/]+)/?.*', DownloadHandler) 

Nếu bạn có khóa blob trong URL, bạn có thể bỏ qua tên tệp trong mã phía máy chủ của mình.

Lợi ích của phương pháp này là các loại nội dung như hình ảnh hoặc PDF mở trực tiếp trong trình duyệt, thuận tiện cho việc xem nhanh. Các loại nội dung khác sẽ chỉ được lưu vào đĩa.

Các vấn đề liên quan