Загрузка Django-s3direct

64
7

Я хочу использовать django-s3direct, и я хочу загрузить много изображений в панель администратора.

1) Все время, когда я пытаюсь загрузить изображение/файл, получает ошибку "К сожалению, загрузка файла не удалась, попробуйте еще раз"? Когда я обновляю страницу. Файл с именем находится на входе. Но мой вход "Сохранить" отключен:/

edit Я удаляю из настроек:

AWS_SECRET_ACCESS_KEY = ''
AWS_ACCESS_KEY_ID = ''
AWS_STORAGE_BUCKET_NAME = ''

и теперь я не получаю ошибку, но файл не загружается:/Все время черновой индикатор выполнения.

2) Как загрузить несколько изображений? Нет встроенного.. Пожалуйста, помогите мне и дайте совет? Im новичок..

У меня Django 1.5.5. Теперь я использую inline, и я не знаю, что дальше.

спросил(а) 2021-01-19T14:33:36+03:00 6 месяцев назад
1
Решение
78

Вам нужно будет отредактировать некоторые свойства разрешений целевого ведра S3, чтобы конечный запрос имел достаточные привилегии для записи в ведро. Войдите в консоль AWS и выберите раздел S3. Выберите нужное ведро и нажмите вкладку "Свойства". Выберите раздел "Разрешения" и предоставлены три параметра (добавьте дополнительные разрешения, измените политику ведра и измените конфигурацию CORS). CORS (совместное использование ресурсов для разных источников) позволит вашему приложению получать доступ к содержимому в ведре S3. Каждое правило должно указывать набор доменов, из которых предоставляется доступ к ведро, а также методы и заголовки, разрешенные для этих доменов.

Чтобы это работало в вашем приложении, нажмите "Добавить конфигурацию CORS и введите следующий XML:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>yourdomain.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Нажмите "Сохранить в окне CORS" и затем "Сохранить снова на вкладке" Свойства "ковшей. Это сообщает S3 разрешить доступ любого домена к ведру, и эти запросы могут содержать любые заголовки. Для обеспечения безопасности вы можете изменить "AllowedOrigin" только для приема запросов из вашего домена. Если вы хотите использовать учетные данные S3 специально для этого приложения, на страницах AWS можно создать больше ключей. Это обеспечивает дополнительную безопасность, поскольку вы можете назначить очень специфический набор запросов, которые может выполнять этот набор ключей. Если это вам предпочтительнее, вам также нужно будет настроить пользователя IAM в опции "Изменить ведро" в вашем ведомости S3. Существуют различные руководства по веб-страницам AWS, в которых подробно описывается, как это можно сделать.

Настройка клиентского кода. Эта настройка не требует дополнительных, нестандартных библиотек Python, но некоторые сценарии необходимы для завершения реализации на стороне клиента. В этой статье рассматривается использование сценария s3upload.js. Получите этот скрипт из репо-проектов (используя Git или иначе) и сохраните его где-нибудь в статическом каталоге приложений. Этот скрипт в настоящее время зависит как от библиотек JQuery, так и от Lo-Dash. Включение их в ваше приложение будет рассмотрено далее в этом руководстве. Теперь HTML и JavaScript могут быть созданы для обработки выбора файла, получения запроса и подписи из вашего приложения Python, а затем, наконец, сделать запрос на загрузку. Во-первых, создайте файл под названием account.html в каталоге шаблонов приложений и запишите заголовок и другие необходимые HTML-теги для вашего приложения. В тело этого файла HTML включается ввод файла и элемент, который будет содержать обновления статуса в процессе загрузки.

<input type="file" id="file" onchange="s3_upload();"/>
<p id="status">Please select a file</p>
<div id="preview"><img src="/static/default.png" /></div>

<form method="POST" action="/submit_form/">
<input type="hidden" id="" name="" value="/static/default.png" />
<input type="text" name="example" placeholder="" /><br />
<input type="text" name="example2" placeholder="" /><br /><br />
<input type="submit" value="" />
</form>

Элемент предварительного просмотра сначала содержит изображение по умолчанию. Оба они обновляются с помощью JavaScript, обсуждаемого ниже, когда пользователь выбирает новое изображение. Таким образом, когда пользователь, наконец, нажимает кнопку отправки, URL-адрес изображения отправляется вместе с другими деталями пользователя на нужную конечную точку для обработки на стороне сервера. Метод JavaScript, s3_upload(), вызывается, когда пользователь выбирает файл. Ниже описывается создание и популяция этого метода. Затем включите три сценария зависимостей в вашем файле HTML, account.html. Возможно, вам придется настроить атрибут src для files3upload.js, если вы поместите этот файл в каталог, отличный от /static:

<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="https://raw.github.com/bestiejs/lodash/v1.1.1/dist/lodash.min.js"></script>
<script type="text/javascript" src="/static/s3upload.js"></script>

Порядок написания сценариев важен, поскольку в этой последовательности должны быть выполнены зависимости. Если вы хотите разместить свои собственные версии JQuery и Lo-Dash, отредактируйте соответственно атрибут thesrc. Наконец, в блоке снова объявите функцию JavaScript s3_upload() в том же файле, чтобы обработать загрузку файла. Этот блок должен будет существовать ниже включения трех зависимостей:

function s3_upload(){
var s3upload = new S3Upload({
file_dom_selector: 'file',
s3_sign_put_url: '/sign_s3_upload/',

onProgress: function(percent, message) {
$('#status').html('Upload progress: ' + percent + '%' + message);
},
onFinishS3Put: function(url) {
$('#status').html('Upload completed. Uploaded to: '+ url);
$("#image_url").val(url);
$("#preview").html('<img src="'+url+'" style="width:300px;" />');
},
onError: function(status) {
$('#status').html('Upload error: ' + status);
}
});
}

Эта функция создает новый экземпляр S3Upload, которому передается элемент ввода файла, URL-адрес, с которого можно получить подписанный запрос и три функции. Изначально функция выполняет запрос к URL-адресу, обозначенному аргументом thes3_sign_put_url, передавая имя файла и тип mime как параметры GET. Код на стороне сервера (см. Следующий раздел) интерпретирует запрос и отвечает предварительным просмотром URL файла загружаемого файла на S3 и подписанного запроса, который затем используется для асинхронной загрузки файла в ваше ведро. Функция отправит обновления для загрузки в функцию onProgress(), и, если загрузка будет успешной, вызывается onFinishS3Put(), и URL-адрес, возвращаемый представлением приложения Python, принимается в качестве аргумента. Если по какой-либо причине загрузка должна завершиться неудачей, вызывается onError(), а параметр thestatus будет описывать ошибку. Если вы обнаружите, что страница не работает так, как вы планируете после внедрения системы, рассмотрите возможность использования console.log() для записи любых ошибок, возникающих внутри обратного вызова onError(), и используйте консоль ошибок браузеров, чтобы помочь диагностировать проблему. В случае успеха предварительный просмотр теперь будет обновлен с выбранным пользователем изображением, а скрытое поле ввода будет содержать URL-адрес изображения. Теперь, как только пользователь выполнит оставшуюся часть формы и щелкнет submit, все части информации могут быть отправлены на одну и ту же конечную точку. Хорошей практикой является информирование пользователя о любой продолжительной деятельности в любой форме приложения (web- или на основе устройства) и для отображения обновлений изменений. Таким образом, методы состояния могут использоваться, например, для отображения GIF загрузки, чтобы указать, что происходит загрузка, которая затем может быть скрыта при завершении загрузки. Без такой информации пользователи могут подозревать, что страница разбилась, и может попытаться обновить страницу или иным образом нарушить процесс загрузки.

Настройка кода Python на стороне сервера

Чтобы создать временную подпись, с которой может быть подписан запрос на загрузку. Эта временная подпись использует данные учетной записи (ключ доступа AWS и секретный ключ доступа) в качестве основы для подписи, но пользователи не будут иметь прямого доступа к этой информации. По истечении срока действия подписи загрузка запросов с одной и той же подписью не будет успешной. Как упоминалось ранее, эта статья посвящена созданию приложения для флеш-фреймворка, хотя шаги для других фреймворков Python будут похожи. Читатели, использующие Python 3, должны рассмотреть соответствующую информацию о веб-сайте Flasks, прежде чем продолжить. Начните с создания основного файла приложения, application.py и настройте свое скелетное приложение соответствующим образом:

from flask import Flask, render_template, request
from hashlib import sha1
import time, os, json, base64, hmac, urllib

app = Flask(__name__)

if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)

В дальнейшем будут использоваться неиспользуемые операторы импорта. Читатели, использующие Python 3, должны импортировать urllib.parse вместо urllib. Затем в том же файле вам нужно будет создать представления, ответственные за возврат правильной информации обратно в браузер пользователей, когда запросы будут сделаны по различным URL-адресам. Сначала определите представление для запросов /account для возврата страницы account.html, которая содержит форму для пользователя:

@app.route("/account/")
def account():
return render_template('account.html')

Обратите внимание, что представления для приложения должны быть размещены между app = Flask(__name__) and if __name__ == '__main__': строки в application.py. Теперь создайте представление в том же файле Python, который отвечает за генерацию и возврат подписи, с которой клиентский JavaScript может загрузить изображение. Это первый запрос, сделанный клиентом перед попыткой загрузки на S3. Это представление отвечает запросами /sign_s3/:

@app.route('/sign_s3/')
def sign_s3():
AWS_ACCESS_KEY = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
S3_BUCKET = os.environ.get('S3_BUCKET')

object_name = request.args.get('s3_object_name')
mime_type = request.args.get('s3_object_type')

expires = int(time.time()+10)
amz_headers = "x-amz-acl:public-read"

put_request = "PUT\n\n%s\n%d\n%s\n/%s/%s" % (mime_type, expires, amz_headers, S3_BUCKET, object_name)

signature = base64.encodestring(hmac.new(AWS_SECRET_KEY, put_request, sha1).digest())
signature = urllib.quote_plus(signature.strip())

url = 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, object_name)

return json.dumps({
'signed_request': '%s?AWSAccessKeyId=%s&Expires=%d&Signature=%s' % (url, AWS_ACCESS_KEY, expires, signature),
'url': url
})

Читатели, использующие Python 3, должны использовать forurib.parse.quote_plus() для цитирования подписи. Этот код выполняет следующие шаги: • Запрос получен в /sign_s3/, а ключи AWS и имя байта S3 загружаются из среды.

• Имя и тип mime подлежащего загрузке объекта извлекаются из параметров GET запроса (этот этап может отличаться в других рамках).

• Время истечения срока действия подписи устанавливается и составляет основу временного характера подписи. Как показано, это лучше всего использовать как функцию относительно текущего времени UNIX. В этом примере подпись истекает через 10 секунд после того, как Python выполнит эту строку кода.

• Строка заголовков указывает S3, какие разрешения доступа предоставлять. В этом случае объект будет общедоступным для загрузки. • Теперь запрос PUT может быть построен из информации об объекте, заголовков и времени истечения.

• Подпись генерируется как хэш SHA скомпилированного секретного ключа AWS и фактического запроса PUT.

• Кроме того, окружающие пробелы удаляются из сигнатуры, а специальные символы экранируются (используя quote_plus) для более безопасной передачи через HTTP.

• Предполагаемый URL-адрес подлежащего загрузке объекта создается как комбинация имени ведра S3 и имени объекта.

• Наконец, подписанный запрос может быть возвращен вместе с предполагаемым URL-адресом в браузер в формате JSON.

Вы можете назначить другое, настроенное имя для объекта вместо того, чтобы использовать тот, с которым уже именован файл, что полезно для предотвращения случайных перезаписей в ведре S3. Например, это имя может быть связано с идентификатором учетной записи пользователя. Если нет, вы должны предоставить некоторый метод для правильного цитирования имени в случае наличия пробелов или других неудобных символов. Кроме того, это этап, на котором вы могли бы обеспечить проверку загруженного файла, чтобы ограничить доступ к определенным типам файлов. Например, простая проверка может быть реализована, чтобы позволить только.png файлам действовать дальше этой точки. Иногда S3 может отвечать 403 (запрещенными) ошибками для запросов, которые подписываются временными сигнатурами, содержащими специальные символы. Поэтому важно правильно привести подпись, как показано выше. Наконец, в application.py создайте представление, ответственное за получение информации об учетной записи после того, как пользователь загрузил изображение, заполнил форму и нажал кнопку submit. Поскольку это будет запрос POST, это также необходимо определить как "разрешенный метод доступа". Этот метод будет отвечать на запросы URL/submit_form/:

@app.route("/submit_form/", methods=["POST"])
def submit_form():
example = request.form[""]
example2 = request.form[""]
image_url = request.form["image_url"]
update_account(example, example2, image_url)
return redirect(url_for('profile'))

В этом примере была вызвана функция update_account(), но создание этого метода в этой статье не рассматривается. На этом этапе вы должны предоставить некоторую функциональность, чтобы приложение могло хранить данные этой учетной записи в некоторой форме базы данных и правильно связывать эту информацию с остальными деталями учетной записи пользователя. Кроме того, URL-адрес страницы профиля не определен в этой статье (или сопутствующем коде). В идеале, например, после обновления учетной записи пользователь будет перенаправлен обратно в свой собственный профиль, чтобы они могли видеть обновленную информацию.

Для получения дополнительной информации http://www.tivix.com/blog/easy-user-uploads-with-direct-s3-uploading/

ответил(а) 2021-01-19T14:33:36+03:00 6 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема