我真的被困在这里。
我希望能够从django表单直接上传到S3。 这将用于保存显示图片。
我遵循了这个:http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html
但遗憾的是我不得不加入
DEFAULT_FILE_STORAGE = 'storages.backends.s3.S3Storage'
由于某种原因到settings.py. django甚至不承认我所做的改变。 (我将其更改为DEFAULT_FILE_STORAGE ='asdsfsdfsdf',它甚至没有出错。 有趣的是,我甚至不知道django-storages是否具有我正在寻找的功能。
答案 0 :(得分:4)
Here's我曾写过的一个工作示例,django-s3upload
。
答案 1 :(得分:3)
这并不太难。步骤是生成策略文档,对其进行签名,然后使用该签名将文件POST到S3。我写了一个名为sbit3的小应用程序。看看这里:https://github.com/victortrac/sbit3/blob/master/server/sbit3.py,特别是PostHandler类:
class PostHandler(tornado.web.RequestHandler):
def _generate_policy_doc(self, conditions, expiration=None):
if not expiration:
# Sets a policy of 15 minutes to upload file
expiration = datetime.datetime.utcnow() + datetime.timedelta(minutes=15)
conditions = [ { "bucket" : conditions["bucket"] },
[ "starts-with", "$key", "uploads/"],
{ "acl" : conditions["acl"] },
{ "success_action_redirect" : conditions["success_action_redirect"] } ]
conditions_json = json.dumps({ "expiration" : expiration.strftime("%Y-%m-%dT%H:%M:%SZ"),
"conditions" : conditions })
logging.debug("Policy doc generated: {0}".format(conditions_json))
return base64.b64encode(conditions_json)
def _sign_policy(self, policy):
signature = base64.b64encode(hmac.new(settings.aws_secret_key, policy, hashlib.sha1).digest())
return signature
def get(self, expiration):
try:
expiration = int(expiration)
# Set max expiration to 7200 minutes (5 days)
if not 0 < expiration < 7200:
raise tornado.web.HTTPError(403)
_expireTimestamp = datetime.datetime.utcnow() + datetime.timedelta(minutes=expiration)
except ValueError:
raise tornado.web.HTTPError(403)
# Associate _uuid to expiration in sdb
_uuid = uuid.uuid4().hex
sdb_conn.add_item(_uuid, expireTimestamp=_expireTimestamp)
conditions = { "bucket" : settings.bucket,
"acl" : settings.acl,
"success_action_redirect" : settings.site_url + "/f/" + _uuid }
policy_document = self._generate_policy_doc(conditions)
signature = self._sign_policy(policy_document)
self.render("post.html", conditions=conditions,
aws_access_id=settings.aws_access_id,
policy_document=policy_document,
signature=signature)
查看设置表单的post.html:
<form action="https://{{ conditions["bucket"] }}.s3.amazonaws.com" method="post" enctype="multipart/form-data">
<input type="hidden" name="key" value="uploads/${filename}">
<input type="hidden" name="AWSAccessKeyId" value="{{ aws_access_id }}">
<input type="hidden" name="acl" value="{{ conditions["acl"] }}">
<input type="hidden" name="success_action_redirect" value="{{ conditions["success_action_redirect"] }}">
<input type="hidden" name="policy" value="{{ policy_document }}">
<input type="hidden" name="signature" value="{{ signature }}">
File to upload to S3:
<input name="file" type="file">
<br>
<input type="submit" value="Upload File to S3">
</form>
答案 2 :(得分:2)
要直接上传到S3(绕过您的网络服务器),您需要直接通过浏览器发布到预先授权的网址。阅读亚马逊的this article,了解它需要如何运作。
我不知道任何能在django中为你做这件事的事情,但要自己提出这个要求并不太难。您还可以使用uploadify之类的内容从浏览器进行实际发布,您只需要为其提供正确的网址。