2012-02-23 78 views
3

我真的被困在这里。直接从django上传到S3

我希望能够从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-storage是否有我正在寻找的功能

+0

你在那个地方有脚本吗?在尝试执行之前它不会给出错误。如果你有这样的脚本,你能发布更多的代码吗? – ABS 2012-02-23 21:40:56

+0

刚才遇到了这个确切的问题 - 你有没有想到这一点? – Andrew 2012-06-18 05:49:57

+0

和我一样,他使用了相同的django-storage应用程序。他链接的说明显示了设置,然后指示使用django shell来查看更改的效果。然而,没有任何变化,Django报告常规的默认文件存储。如果我解决它,我会在这里更新。 – Guerry 2012-09-05 14:13:46

回答

2

In为了直接上传到S3(绕过你的网络服务器),你将需要直接通过浏览器发布到一个预先授权的网址从亚马逊读取this article,它解释了它需要如何工作。这将在django中为你完成,但你自己提出请求并不困难,你也可以使用类似uploadify这样的东西来做浏览器的实际发布,你只需要给它正确的url。

2

这并不难。这些步骤是生成一个策略文档,对其签名,然后使用该签名将文件发布到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> 
4

Here's工作的例子,我曾经写道:django-s3upload