سؤال

أخطط لإنشاء تطبيق ويب يسمح للمستخدمين بتخفيض ملفات مشروع الاستوديو المرئي الخاصة بهم.ومع ذلك، يبدو أن Google App Engine يقبل تحميل الملفات وتخزينها على خادم Google من خلاله db.TextProperty و db.BlobProperty.

يسعدني أن يتمكن أي شخص من تقديم نموذج التعليمات البرمجية (سواء العميل أو جانب الخادم) حول كيفية القيام بذلك.

هل كانت مفيدة؟

المحلول

هنا ملف كامل وعملي.لقد قمت بسحب النسخة الأصلية من موقع Google وقمت بتعديلها لجعلها أكثر واقعية قليلاً.

بعض الأشياء التي يجب ملاحظتها:

  1. يستخدم هذا الرمز واجهة برمجة تطبيقات بلوبستور
  2. الغرض من هذا الخط في فئة ServiceHandler هو "إصلاح" المفتاح بحيث يتخلص من أي اسم قد يكون قد حدث في المتصفح (لم ألاحظ أيًا في الكروم)

    blob_key = str(urllib.unquote(blob_key))
    
  3. يعد شرط "save_as" الموجود في نهاية هذا أمرًا مهمًا.سيتأكد من عدم تشويه اسم الملف عند إرساله إلى متصفحك.تخلص منه لملاحظة ما يحدث.

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

حظ سعيد!

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 __name__ == '__main__':
  main()

نصائح أخرى

في الواقع، تمت الإجابة على هذا السؤال في وثائق App Egnine.انظر مثالا على تحميل صور المستخدم.

كود HTML، داخل <form></form>:

<input type="file" name="img"/>

رمز بايثون:

class Guestbook(webapp.RequestHandler):
  def post(self):
    greeting = Greeting()
    if users.get_current_user():
      greeting.author = users.get_current_user()
    greeting.content = self.request.get("content")
    avatar = self.request.get("img")
    greeting.avatar = db.Blob(avatar)
    greeting.put()
    self.redirect('/')

يوجد موضوع في مجموعات Google حول هذا الموضوع:

تحميل الملفات

ومع وجود الكثير من التعليمات البرمجية المفيدة، ساعدتني هذه المناقشة كثيرًا في تحميل الملفات.

أصدرت Google خدمة لتخزين الملفات الكبيرة.القي نظرة على وثائق API blobstore.إذا كان حجم ملفاتك أكبر من 1 ميجابايت، فيجب عليك استخدامها.

قمت بتجربته اليوم وهو يعمل كالآتي:

إصدار sdk الخاص بي هو 1.3.x

صفحة أتش تي أم أل:

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

رمز الخادم:

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

إذا كنت لا تزال تواجه مشكلة، فتأكد من أنك تستخدم enctype في علامة النموذج

لا:

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

نعم:

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

لا يمكنك تخزين الملفات لأنه لا يوجد نظام ملفات تقليدي.يمكنك فقط تخزينها في DataStore الخاص بهم (في حقل محدد على أنه BlobProperty)

ويوجد مثال في الرابط السابق:

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

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

شخصيا وجدت البرنامج التعليمي الموصوف هنا مفيد عند استخدام وقت تشغيل Java مع GAE.لسبب ما، عندما حاولت تحميل ملف باستخدام

<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>

لقد وجدت أن فئة HttpServlet الخاصة بي لسبب ما لن تقبل النموذج الذي يحتوي على السمة "enctype".ومع ذلك، فإن إزالته تعمل، وهذا يعني أنه لا يمكنني تحميل أي ملفات.

لا يوجد تخزين ثابت للملفات في Google App Engine.كل شيء يجب أن يذهب إلى مخزن البيانات والتي تشبه إلى حد ما قاعدة البيانات العلائقية ولكن ليس تمامًا.

هل يمكن تخزين الملفات كما TextProperty أو BlobProperty صفات.

يوجد حد 1 ميجا بايت لإدخالات DataStore والتي قد تكون أو لا تمثل مشكلة.

لقد لاحظت بعض السلوك الغريب عند تحميل الملفات على App Engine.عند تقديم النموذج التالي:

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

ومن ثم تقوم باستخراج img من الطلب مثل هذا:

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

ال img_contents المتغير هو str() في Google Chrome، ولكنه Unicode في Firefox.وكما أنت الآن، db.Blob() يأخذ المُنشئ سلسلة وسيقوم بإلقاء خطأ إذا قمت بتمرير سلسلة Unicode.

هل يعرف أحد كيف يمكن إصلاح هذا؟

وما أجده غريبًا تمامًا هو أنه عندما أقوم بنسخ تطبيق سجل الزوار (مع الصور الرمزية) ولصقه، فإنه يعمل بشكل مثالي.أفعل كل شيء بنفس الطريقة تمامًا في الكود الخاص بي، لكنه لن ينجح.أنا قريب جدًا من سحب شعري.

هناك طريقة للاستخدام نظام الملفات المسطحة(على الأقل من منظور الاستخدام)

هناك هذا مشروع Google App Engine Virtual FileSystem.يتم تنفيذه بمساعدة مخزن البيانات وواجهات برمجة تطبيقات memcache لمحاكاة نظام ملفات عادي.باستخدام هذه المكتبة يمكنك استخدامها في مشروعك أ وصول مماثل لنظام الملفات (القراءة والكتابة).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top