2012-02-23 155 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