Python 从django直接上传到S3

Python 从django直接上传到S3,python,django,django-forms,amazon-s3,Python,Django,Django Forms,Amazon S3,我真的被困在这里了 我希望能够从django表单直接上传到S3。 这将用于保存显示图片 我接着说: 但不幸的是,我无法添加 DEFAULT_FILE_STORAGE = 'storages.backends.s3.S3Storage' 由于某种原因,无法访问settings.py。django甚至不认识我所做的改变。(我将其更改为默认的_FILE_STORAGE='asdsfsdfsdf',甚至没有给出错误。 有趣的是,我甚至不知道django storages是否具有我正在寻找的功能。为了直

我真的被困在这里了

我希望能够从django表单直接上传到S3。 这将用于保存显示图片

我接着说:

但不幸的是,我无法添加

DEFAULT_FILE_STORAGE = 'storages.backends.s3.S3Storage'
由于某种原因,无法访问settings.py。django甚至不认识我所做的改变。(我将其更改为默认的_FILE_STORAGE='asdsfsdfsdf',甚至没有给出错误。
有趣的是,我甚至不知道django storages是否具有我正在寻找的功能。

为了直接上传到S3(绕过您的Web服务器),您需要直接通过浏览器发布到预先授权的url。请阅读amazon上的说明,了解其工作原理


我不知道在django有什么能帮你做到这一点,但你自己提出请求并不太困难。你也可以使用类似的方法从浏览器中进行实际发布,你只需要给它一个正确的url。

这并不太难。步骤是生成一个策略文档,签名,然后使用该签名我编写了一个名为sbit3的小应用程序来实现这一点。请看这里:,特别是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)
类PostHandler(tornado.web.RequestHandler):
定义_生成_策略_文档(自身、条件、到期=无):
如果未到期:
#设置15分钟上载文件的策略
expiration=datetime.datetime.utcnow()+datetime.timedelta(分钟=15)
条件=[{“bucket”:条件[“bucket”]},
[“以“,“$key”,“uploads/”开头],
{“acl”:条件[“acl”]},
{“成功动作重定向”:条件[“成功动作重定向”]}]
条件_json=json.dumps({“expiration”:expiration.strftime(“%Y-%m-%dT%H:%m:%SZ”),
“条件”:条件})
logging.debug(“生成的策略文档:{0}”。格式(conditions_json))
返回base64.b64encode(条件\u json)
定义签名策略(自我、策略):
signature=base64.b64encode(hmac.new(settings.aws\u secret\u key,policy,hashlib.sha1.digest())
返回签名
def get(自身、到期):
尝试:
expiration=int(过期)
#将最大过期时间设置为7200分钟(5天)
如果不是0<到期<7200:
升起tornado.web.HTTPError(403)
_expireTimestamp=datetime.datetime.utcnow()+datetime.timedelta(分钟=到期)
除值错误外:
升起tornado.web.HTTPError(403)
#将uuid与sdb中的到期关联
_uuid=uuid.uuid4().hex
sdb连接添加项(\u uuid,expireTimestamp=\u expireTimestamp)
条件={“bucket”:settings.bucket,
“acl”:settings.acl,
“成功\u操作\u重定向”:settings.site\u url+“/f/”+\u uuid}
策略\文档=自身。\生成策略\文档(条件)
签名=自我签名政策(政策文件)
self.render(“post.html”,conditions=conditions,
aws\u访问\u id=settings.aws\u访问\u id,
政策文件=政策文件,
签名=签名)
查看设置表单的:

<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> 

要上载到S3的文件:


我曾经写过一个工作示例,
django-s3upload

你在那个位置有脚本吗?它在尝试执行之前不会给出错误。如果你有这样的脚本,你能发布更多的代码吗?正好遇到了这个问题——你有没有发现这个问题?就像我一样,使用他以前使用的django存储应用程序他链接到的说明显示了设置,然后指示一个人使用django shell查看生效的更改。但是,没有任何更改,django报告常规默认文件存储。如果我解决了它,我将在此处更新。此答案帮助我: