Ich plane, eine Web-App zu erstellen, mit der Benutzer ihre Visual Studio-Projektdateien herunterstufen können. Es scheint jedoch, dass Google App Engine das Hochladen von Dateien und das Speichern von Flatfiles auf dem Google Server über db.TextProperty
und akzeptiert db.BlobProperty
.
Ich bin froh, dass jeder ein Codebeispiel (sowohl auf Client- als auch auf Serverseite) bereitstellen kann, wie dies getan werden kann.
python
google-app-engine
Graviton
quelle
quelle
Antworten:
Hier ist eine vollständige Arbeitsdatei. Ich habe das Original von der Google-Website abgerufen und geändert, um es etwas realer zu gestalten.
Ein paar Dinge zu beachten:
Der Zweck dieser Zeile in der ServeHandler-Klasse besteht darin, den Schlüssel so zu "reparieren", dass alle im Browser möglicherweise aufgetretenen Namensverfälschungen beseitigt werden (in Chrome habe ich keine beobachtet).
Die "save_as" -Klausel am Ende ist wichtig. Dadurch wird sichergestellt, dass der Dateiname beim Senden an Ihren Browser nicht beschädigt wird. Werde es los, um zu beobachten, was passiert.
self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)
Viel Glück!
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="https://stackoverflow.com/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()
quelle
self.__uploads
inblobstore_handler
ist ,None
wenn ich das versuchen.Tatsächlich wird diese Frage in der App Egnine-Dokumentation beantwortet. Siehe ein Beispiel zum Hochladen von Benutzerbildern .
HTML-Code in <form> </ form>:
Python-Code:
quelle
In Google Groups gibt es einen Thread dazu:
Dateien hochladen
Mit viel nützlichem Code hat mir diese Diskussion beim Hochladen von Dateien sehr geholfen.
quelle
Google hat einen Dienst zum Speichern großer Dateien veröffentlicht. Schauen Sie sich die Dokumentation zur blobstore-API an . Wenn Ihre Dateien> 1 MB groß sind, sollten Sie sie verwenden.
quelle
Ich versuche es heute, es funktioniert wie folgt:
meine sdk version ist 1.3.x.
HTML-Seite:
<form enctype="multipart/form-data" action="/upload" method="post" > <input type="file" name="myfile" /> <input type="submit" /> </form>
Servercode:
file_contents = self.request.POST.get('myfile').file.read()
quelle
Wenn Sie immer noch ein Problem haben, überprüfen Sie, ob Sie im Formular-Tag enctype verwenden
Nein:
<form encoding="multipart/form-data" action="/upload">
Ja:
<form enctype="multipart/form-data" action="/upload">
quelle
Sie können keine Dateien speichern, da es kein herkömmliches Dateisystem gibt. Sie können sie nur in ihrem eigenen DataStore speichern (in einem Feld, das als BlobProperty definiert ist ).
Im vorherigen Link gibt es ein Beispiel:
class MyModel(db.Model): blob = db.BlobProperty() obj = MyModel() obj.blob = db.Blob( file_contents )
quelle
Persönlich fand ich das hier beschriebene Tutorial nützlich, wenn ich die Java-Laufzeit mit GAE verwende. Aus irgendeinem Grund, als ich versuchte, eine Datei mit hochzuladen
<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>
Ich habe festgestellt, dass meine HttpServlet-Klasse aus irgendeinem Grund das Formular mit dem Attribut 'enctype' nicht akzeptiert. Das Entfernen funktioniert jedoch. Dies bedeutet, dass ich keine Dateien hochladen kann.
quelle
In Google App Engine wird keine Flatfile gespeichert. Alles muss in den Datenspeicher gehen, der ein bisschen wie eine relationale Datenbank ist, aber nicht ganz.
Sie können die Dateien als TextProperty- oder BlobProperty- Attribute speichern .
Es gibt eine Beschränkung von 1 MB für DataStore-Einträge, die möglicherweise ein Problem darstellen oder nicht.
quelle
Ich habe beim Hochladen von Dateien auf App Engine ein merkwürdiges Verhalten festgestellt. Wenn Sie das folgende Formular einreichen:
<form method="post" action="/upload" enctype="multipart/form-data"> <input type="file" name="img" /> ... </form>
Und dann extrahieren Sie das
img
aus der Anfrage wie folgt:img_contents = self.request.get('img')
Die
img_contents
Variable ist einestr()
in Google Chrome, in Firefox jedoch Unicode. Und wie Sie jetzt nimmt derdb.Blob()
Konstruktor eine Zeichenfolge und gibt einen Fehler aus, wenn Sie eine Unicode-Zeichenfolge übergeben.Weiß jemand, wie dies behoben werden kann?
Was ich absolut seltsam finde, ist, dass das Kopieren und Einfügen der Gästebuchanwendung (mit Avataren) perfekt funktioniert. Ich mache alles genauso in meinem Code, aber es wird einfach nicht funktionieren. Ich bin sehr nahe daran, mir die Haare auszureißen.
quelle
Es gibt eine Möglichkeit, ein Flat-File-System zu verwenden (zumindest in der Nutzungsperspektive).
Es gibt dieses virtuelle Dateisystemprojekt von Google App Engine . Dies wird mithilfe von Datenspeicher- und Memcache-APIs implementiert, um ein gewöhnliches Dateisystem zu emulieren. Mit dieser Bibliothek können Sie in Ihrem Projekt einen ähnlichen Dateisystemzugriff (Lesen und Schreiben) projizieren .
quelle