it-swarm-vi.tech

Tải lên tệp trong Google App Engine

Tôi đang lên kế hoạch tạo một ứng dụng web cho phép người dùng hạ cấp các tệp dự án phòng thu trực quan của họ. Tuy nhiên, có vẻ như Google App Engine chấp nhận tải lên các tệp và lưu trữ tệp phẳng trên Máy chủ Google thông qua db.TextPropertydb.BlobProperty.

Tôi sẽ vui mừng bất cứ ai cũng có thể cung cấp mẫu mã (cả máy khách và phía máy chủ) về cách thực hiện việc này.

77
Graviton

Đây là một tập tin đầy đủ, làm việc. Tôi lấy bản gốc từ trang Google và sửa đổi nó để biến nó thành thế giới thực hơn một chút.

Một vài điều cần chú ý:

  1. Mã này sử dụng API BlobStore
  2. Mục đích của dòng này trong lớp ServeHandler là "sửa" khóa để nó thoát khỏi bất kỳ sự xáo trộn tên nào có thể xảy ra trong trình duyệt (Tôi không quan sát thấy bất kỳ điều gì trong Chrome)

    blob_key = str(urllib.unquote(blob_key))
    
  3. Mệnh đề "save_as" ở cuối phần này rất quan trọng. Nó sẽ đảm bảo rằng tên tệp không bị sai khi gửi đến trình duyệt của bạn. Loại bỏ nó để quan sát những gì xảy ra.

    self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)
    

Chúc may mắn!

import os
import urllib

from google.appengine.ext import blobstore
from google.appengine.ext import webapp
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app

class MainHandler(webapp.RequestHandler):
    def get(self):
        upload_url = blobstore.create_upload_url('/upload')
        self.response.out.write('<html><body>')
        self.response.out.write('<form action="%s" method="POST" enctype="multipart/form-data">' % upload_url)
        self.response.out.write("""Upload File: <input type="file" name="file"><br> <input type="submit" name="submit" value="Submit"> </form></body></html>""")

        for b in blobstore.BlobInfo.all():
            self.response.out.write('<li><a href="/serve/%s' % str(b.key()) + '">' + str(b.filename) + '</a>')

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        upload_files = self.get_uploads('file')
        blob_info = upload_files[0]
        self.redirect('/')

class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self, blob_key):
        blob_key = str(urllib.unquote(blob_key))
        if not blobstore.get(blob_key):
            self.error(404)
        else:
            self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)

def main():
    application = webapp.WSGIApplication(
          [('/', MainHandler),
           ('/upload', UploadHandler),
           ('/serve/([^/]+)?', ServeHandler),
          ], debug=True)
    run_wsgi_app(application)

if __== '__main__':
  main()
42
010110110101

Trong thực tế, câu hỏi này được trả lời trong tài liệu Ứng dụng Egnine. Xem ví dụ trên Tải lên hình ảnh người dùng .

Mã HTML, bên trong <form> </ form>:

<kiểu nhập = "tệp" name = "img" />

Mã Python:

class Guestbook (webapp.RequestHandler): [.__.] def post (self): [.__.] chúc mừng = lời chào () [.__.] if users.get_cản_user (): [.__.] users.get_cản_user () [.__.] hello.content = self.request.get ("nội dung") [.__.] avatar = self.request.get ("img") [.__.] hello.avatar = db.Blob (avatar) [.__.] hello.put () [.__.] self.redirect ('/')
49
sastanin

Có một chủ đề trong Google Groups về nó:

Tải tệp lên

Với rất nhiều mã hữu ích, cuộc thảo luận đó đã giúp tôi rất nhiều trong việc tải lên các tệp.

10
Gustavo Diaz Jaimes

Tôi thử nó ngày hôm nay, Nó hoạt động như sau:

phiên bản sdk của tôi là 1.3.x

trang html:

<form enctype="multipart/form-data" action="/upload" method="post" > 
<input type="file" name="myfile" /> 
<input type="submit" /> 
</form> 

Mã máy chủ:

file_contents = self.request.POST.get('myfile').file.read() 
6
Bili

Google đã phát hành một dịch vụ để lưu trữ các tệp lớn. Hãy xem tài liệu API của blobstore . Nếu tệp của bạn> 1MB, bạn nên sử dụng nó.

6
jbochi

Nếu bạn vẫn gặp sự cố, hãy kiểm tra xem bạn có đang sử dụng enctype trong thẻ biểu mẫu không

Không:

<form encoding="multipart/form-data" action="/upload">

Vâng:

<form enctype="multipart/form-data" action="/upload">
3
Joe Petrini

Bạn không thể lưu trữ tệp vì không có hệ thống tệp truyền thống. Bạn chỉ có thể lưu trữ chúng trong DataStore của riêng họ (trong trường được xác định là BlobProperty )

Có một ví dụ trong liên kết trước:

class MyModel(db.Model):
  blob = db.BlobProperty()

obj = MyModel()
obj.blob = db.Blob( file_contents )
1
Guido

Cá nhân tôi thấy hướng dẫn được mô tả tại đây hữu ích khi sử dụng Java thời gian chạy với GAE. Vì một số lý do, khi tôi cố tải lên một tệp bằng cách sử dụng

<form action="/testservelet" method="get" enctype="multipart/form-data">
    <div>
        Myfile:<input type="file" name="file" size="50"/>
    </div>

    <div>
        <input type="submit" value="Upload file">
    </div>
</form>

Tôi thấy rằng lớp httpServlet của tôi vì một số lý do sẽ không chấp nhận biểu mẫu với thuộc tính 'enctype'. Tuy nhiên, việc xóa nó hoạt động, điều này có nghĩa là tôi không thể tải lên bất kỳ tệp nào.

1
Vijay Sharma

Có một cách sử dụng hệ thống tệp phẳng (Toàn bộ trong phối cảnh sử dụng)

Có điều này Dự án Hệ thống tệp ảo của Google App Engine . được triển khai với sự trợ giúp của API kho dữ liệu và memcache để mô phỏng một hệ thống tệp thông thường. Sử dụng thư viện này, bạn có thể sử dụng trong dự án một quyền truy cập hệ thống tệp tương tự (đọc và ghi) .

0
vivek_jonam

Không có lưu trữ tệp phẳng trong Google App Engine. Mọi thứ phải đi vào Kho dữ liệ giống như một cơ sở dữ liệu quan hệ nhưng không hoàn toàn.

Bạn có thể lưu trữ các tệp dưới dạng TextProperty hoặc BlobProperty thuộc tính.

Có giới hạn 1 MB cho các mục DataStore có thể có hoặc không có vấn đề.

0
Dave Webb

Tôi đã quan sát thấy một số hành vi lạ khi tải lên các tệp trên Máy ứng dụng. Khi bạn gửi mẫu sau:

<form method="post" action="/upload" enctype="multipart/form-data">
    <input type="file" name="img" />
    ...
</form>

Và sau đó bạn trích xuất img từ yêu cầu như thế này:

img_contents = self.request.get('img')

Biến img_contents Là một str() trong Google Chrome, nhưng nó là unicode trong Firefox. Và như bạn bây giờ, hàm tạo db.Blob() nhận một chuỗi và sẽ đưa ra lỗi nếu bạn truyền vào một chuỗi unicode.

Có ai biết làm thế nào điều này có thể được sửa chữa?

Ngoài ra, điều tôi thấy hoàn toàn lạ là khi tôi sao chép và dán ứng dụng Sổ lưu bút (có hình đại diện), nó hoạt động hoàn hảo. Tôi làm mọi thứ chính xác theo cùng một cách trong mã của mình, nhưng nó sẽ không hoạt động. Tôi rất gần để kéo tóc ra.

0
Honza Pokorny