Загрузить прямо на S3 из Django - PullRequest
3 голосов
/ 24 февраля 2012

Я действительно застрял здесь.

Я хочу иметь возможность загружать напрямую в S3 из формы Django. Это будет использоваться для хранения отображаемых изображений.

Я следовал этому: http://django -storages.readthedocs.org / en / latest / backends / amazon-S3.html

но, к сожалению, я застреваю при добавлении

DEFAULT_FILE_STORAGE = 'storages.backends.s3.S3Storage'

в settings.py по какой-то причине. Джанго даже не признает изменения, которые я сделал. (Я изменил его на DEFAULT_FILE_STORAGE = 'asdsfsdfsdf', и он даже не выдал ошибку. Самое смешное, что я даже не знаю, есть ли у django-хранилищ функция, которую я ищу.

Ответы [ 3 ]

4 голосов
/ 19 марта 2013

Вот рабочий пример, который я однажды написал, django-s3upload.

3 голосов
/ 05 сентября 2012

Это не так уж сложно.Шаги состоят в том, чтобы сгенерировать документ политики, подписать его, а затем использовать эту подпись, чтобы отправить файл на 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 голосов
/ 24 февраля 2012

Для того, чтобы загрузить напрямую на S3 (в обход вашего веб-сервера), вам нужно будет напрямую отправить через браузер предварительно авторизованный URL-адрес.Прочитайте эту статью от Amazon, в которой объясняется, как она должна работать.

Я не знаю ничего, что сделает это для вас в Django, но не так уж сложно сделатьзапросить себяВы также можете использовать что-то вроде uploadify , чтобы сделать фактическую публикацию из браузера, вам просто нужно дать ей правильный URL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...