Blobstore API (рднрд╛рдЧ 1) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреНрд░реЙрдкрдмреЙрдХреНрд╕ рд╕реЗрд╡рд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛

Blobstore api - рдРрдк рдЗрдВрдЬрди рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХреА рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдкреБрдирдГрдкреВрд░реНрддрд┐, рдЖрдкрдХреЛ рдмрдбрд╝реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ, рд╡рд░реНрддрдорд╛рди рдореЗрдВ 2Gb ( рдореВрд▓ - 50Mb, рд▓рдЧрднрдЧред рдЯреНрд░рд╛рдВрд╕рд▓реЗрдЯрд░ ) рддрдХред рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рднреА рд╕рдмрд╕реЗ рдХрдард┐рди рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рдиреЛрдЯреНрд╕ рдХреА рдПрдХ рдЫреЛрдЯреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рджрд┐рдЦрд╛рдПрдЧреА рдХрд┐ рдмреНрд▓реЙрдмрд╕реНрдЯреЛрд░ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдРрдк рдЗрдВрдЬрди рдкрд░ рдЖрдзрд╛рд░рд┐рдд "рдбреНрд░реЙрдкрдмреЙрдХреНрд╕" рд╕реЗрд╡рд╛ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдмреБрдирд┐рдпрд╛рджреА рдмрд╛рддреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ, рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдПрдХ рдбреЗрдЯрд╛рд╕реНрдЯреЛрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗ рдФрд░ рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рд▓реМрдЯрд╛рдПрдВрдЧреЗред



рдЪрд▓рд┐рдП рдЕрдкрд▓реЛрдб рдлреЙрд░реНрдо рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдЪрд░рдг рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд╣реИ: рд╣рдо рдПрдХ рдорд╛рдирдХ рдПрдЪрдЯреАрдПрдордПрд▓ рдлреЙрд░реНрдо рдмрдирд╛рддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рд╣рдореЗрдВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рд╡рд╣ рд╣реИ рдлреЙрд░реНрдо рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд▓рд┐рдП blobstore.create_upload_url рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдФрд░ рд╡рд╛рдВрдЫрд┐рдд рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде URL рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдХреЗред рдиреАрдЪреЗ рд╣рдорд╛рд░рд╛ рдХреЛрдб рд╣реИ:

class FileUploadFormHandler(BaseHandler): @util.login_required def get(self): self.render_template("upload.html", { 'form_url': blobstore.create_upload_url('/upload'), 'logout_url': users.create_logout_url('/'), })
      
      





рд╕рдм рдХреБрдЫ рдорд╛рдирдХ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ - рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо google.appengine.ext.webapp.util рдкреИрдХреЗрдЬ рд╕реЗ login_required рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд▓реЙрдЧ рдЗрди рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ (рдФрд░ рдЕрдиреНрдпрдерд╛ рд▓реЙрдЧрд┐рди рдкрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред рдФрд░ рдпрд╣ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╣реИ:

 <html> <head> <title> </title> </head> <body> <p style="float: right"><a href="{{logout_url}}">Log Out</a></p> <h1>Upload a file to App Engine File Hangar</h1> <form method="POST" action="{{form_url}}" enctype="multipart/form-data"> <input type="file" name="file" /><br /> <input type="submit" value="Upload" /> </form> </body> </html>
      
      





рдлрд╝реЙрд░реНрдо рдЯреИрдЧ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ: рд╡рд┐рдзрд┐ "POST" рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдФрд░ enctype "рдорд▓реНрдЯреАрдкрд╛рд░реНрдЯ / рдлреЙрд░реНрдо-рдбреЗрдЯрд╛" рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЕрдиреНрдпрдерд╛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛!



рдЖрдЧреЗ рд╣рдо рдПрдХ рдмреВрдЯ рд╣реИрдВрдбрд▓рд░ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЪрд▓реЛ рдбрд╛рдЙрдирд▓реЛрдб рдХреА рдЧрдИ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЙрдбрд▓ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдпрд╣ рд╣реИ:

 class FileInfo(db.Model): blob = blobstore.BlobReferenceProperty(required=True) uploaded_by = db.UserProperty(required=True) uploaded_at = db.DateTimeProperty(required=True, auto_now_add=True)
      
      





рд╕реБрдВрджрд░ рдорд╛рдирдХ рдореЙрдбрд▓, blobstore.BlobReferenceProperty рдХреЗ 'рдмреВрдБрдж' рдлрд╝реАрд▓реНрдб рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рдеред BlobReferenceProperty ReferenceProperty рдХреЗ рд╕рдорд╛рди рд╣реИ, рдПрдХрдорд╛рддреНрд░ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдЕрдиреНрдп рдореЙрдбрд▓ рдХреЛ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ Blob рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЕрдиреБрд░реЛрдз рдкрд░, BlobInfo рдСрдмреНрдЬреЗрдХреНрдЯ рд╡рд╛рдкрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред



рдбрд╛рдЙрдирд▓реЛрдб рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рд╕реАрдзреЗ рдЬрд┐рдореНрдореЗрджрд╛рд░ рдХреЛрдб:

 class FileUploadHandler(blobstore_handlers.BlobstoreUploadHandler): def post(self): blob_info = self.get_uploads()[0] if not users.get_current_user(): blob_info.delete() self.redirect(users.create_login_url("/")) return file_info = FileInfo(blob=blob_info.key(), uploaded_by=users.get_current_user()) db.put(file_info) self.redirect("/file/%d" % (file_info.key().id(),))
      
      





рдЪрд▓реЛ рдЪрд░рдгреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣реИрдВрдбрд▓рд░ рд╕рд╛рдорд╛рдиреНрдп webapp рдХреЗ рдмрдЬрд╛рдп BlobstoreUploadHandler рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИред RequestHandlerред BlobstoreUploadHandler рдПрдХ рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐, self.get_uploads () рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬреЛ BlobInfo рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреА рд╕реВрдЪреА рджреЗрддрд╛ рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рдбрд╛рдЙрдирд▓реЛрдб рдХреА рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдПред



рдкреЛрд╕реНрдЯ () рд╡рд┐рдзрд┐ рдореЗрдВ, рд╣рдо self.get_uploads () рдХрд╣рддреЗ рд╣реИрдВ рдФрд░ рдкрд╣рд▓реЗ рддрддреНрд╡ рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдмреНрд▓реЙрдмрд╕реНрдЯреЛрд░ рдПрдкреАрдЖрдИ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдХ рдлреЙрд░реНрдо рдореЗрдВ рдХрдИ рдлрд╝рд╛рдЗрд▓ рдЕрдкрд▓реЛрдб рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдПрдХ рддрддреНрд╡ рд╣рдореЗрд╢рд╛ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддрд╛ рд╣реИ, рд╣рдо рдмрд╕ рдЗрд╕реЗ рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВ ( рдкрд╣рд▓реЗ рд╕реЗ рд╕рдорд░реНрдерд┐рдд, рд▓рдЧрднрдЧред рдЕрдиреБрд╡рд╛рджрдХ )ред рдлрд┐рд░, рд╣рдо рдЦреБрдж рдХреЛ рдЕрдирдзрд┐рдХреГрдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рд╕реЗ рдмрдЪрд╛рддреЗ рд╣реИрдВ рдЬреЛ рдлреЙрд░реНрдо рдХреЛ рдПрдХ рдпрд╛ рджреВрд╕рд░реЗ рддрд░реАрдХреЗ рд╕реЗ рд╕рдмрдорд┐рдЯ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рд╣рдо рдбрд╛рдЙрдирд▓реЛрдб рдкреНрд░рдпрд╛рд╕ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХреГрдд рдирд╣реАрдВ рдереЗ, рддреЛ рд╣рдо рдпрд╣рд╛рдВ login_required рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдВрдд рдореЗрдВ, рд╣рдо рдбрд╛рдЙрдирд▓реЛрдб рдХреА рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рд╕реНрдЯреЛрд░ рдореЗрдВ рдПрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдирдП рдЬреЛрдбрд╝реЗ рдЧрдП рдлрд╝рд╛рдЗрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВред



рдЕрдЧрд▓рд╛ рдХрджрдо рдПрдХ рд╣реИрдВрдбрд▓рд░ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реИ рдЬреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХреА рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдВ рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ:

 class FileInfoHandler(BaseHandler): def get(self, file_id): file_info = FileInfo.get_by_id(long(file_id)) if not file_info: self.error(404) return self.render_template("info.html", { 'file_info': file_info, 'logout_url': users.create_logout_url('/'), })
      
      





рдФрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкреНрд▓реЗрдЯ:

 <html> <head> <title>  </title> </head> <body> <p style="float: right"><a href="{{logout_url}}">Log Out</a></p> <h1>  </h1> <table> <tr><th> </th><td>{{file_info.blob.filename}}</td></tr> <tr><th></th><td>{{file_info.blob.size}} bytes</td></tr> <tr><th> </th><td>{{file_info.uploaded_at}}</td></tr> <tr><th> </th><td>{{file_info.uploaded_by}}</td></tr> <tr><th>Content Type</th><td>{{file_info.blob.content_type}}</td></tr> </table> <p><a href="/file/{{file_info.key.id}}/download">  </a></p> </body> </html>
      
      





рдЕрдВрдд рдореЗрдВ, рдПрдХ рд╣реИрдВрдбрд▓рд░ рдЬреЛ рд╕реАрдзреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдлрд╛рдЗрд▓ рджреЗрддрд╛ рд╣реИ:

 class FileDownloadHandler(blobstore_handlers.BlobstoreDownloadHandler): def get(self, file_id): file_info = FileInfo.get_by_id(long(file_id)) if not file_info or not file_info.blob: self.error(404) return self.send_blob(file_info.blob, save_as=True)
      
      





рдпрд╣рд╛рдВ, рд╣рдо рдХреБрдВрдЬреА рджреНрд╡рд╛рд░рд╛ FileInfo рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рдпрд╣ рдореМрдЬреВрдж рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдПрдХ рдмреВрдБрдж рд╣реИ, рддреЛ рд╣рдо send_blob рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ рдХреЛ рдореВрд▓ рд╡рд░реНрдЧ BlobstoreDownloadHandler рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред рд╣рдо True рдкрд░ рд╕реЗрдЯ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХ 'save_as' рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИ рдХрд┐ рдлрд╝рд╛рдЗрд▓ рдбрд╛рдЙрдирд▓реЛрдб рдХреЗ рд▓рд┐рдП рднреЗрдЬреА рдЬрд╛рдПрдЧреА, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдирд╣реАрдВред рд╣рдо рд╡рд┐рд╢рд┐рд╖реНрдЯ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП True рдХреЗ рдмрдЬрд╛рдп рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рднреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдпрд╣ рд╡рд╣ рдирд╛рдо рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдлрд╝рд╛рдЗрд▓ рдбрд╛рдЙрдирд▓реЛрдб рдХреА рдЧрдИ рдереАред



рдпрд╣ рд▓реЗрдЦ рдХреЗрд╡рд▓ рд╕рддрд╣реА рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдмреНрд▓реЙрдмрд╕реНрдЯреЛрд░ рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдзрд┐рдХ рд╕рдВрдкреВрд░реНрдг рдЪрд┐рддреНрд░ рдХреЗ рд▓рд┐рдП, рдЖрдк рдкреНрд░рд▓реЗрдЦрди рд╕реЗ рдмрд╣реБрдд рдХреБрдЫ рд╕реАрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдпреЗ рдЖрд╡рд╢реНрдпрдХ рдореВрд▓ рдмрд╛рддреЗрдВ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ рд╣рдо рдХреБрдЫ рдирдпрд╛ рдХрд░реЗрдВрдЧреЗ: рдмреЗрд╣рддрд░ рдЕрдиреБрднрд╡ рдХреЗ рдЕрдиреБрднрд╡ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдпрд╛ рдлреНрд▓реИрд╢ рдореЗрдВ рдбрд╛рдЙрдирд▓реЛрдб рд╡рд┐рдЬреЗрдЯ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдЬреЛрдбрд╝реЗрдВ!

рдЬреЛ рд▓реЛрдЧ рдЗрд╕реЗ рд╕рднреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЙрдирдХреЗ рд▓рд┐рдП рдбреЗрдореЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб рдпрд╣рд╛рдВ рдЙрдкрд▓рдмреНрдз рд╣реИ ред



All Articles