Как получить ключ объекта aws s3 с помощью django-storerages и boto3

Я использую django-storage и boto3 для мультимедийных и статических файлов с помощью aws s3. Мне нужно получить ключ объекта ведра aws s3, чтобы я мог сгенерировать URL-адрес для этого объекта.

client = boto3.client('s3')
bucket_name = 'django-bucket'

key = ???

u = client.generate_presigned_url('get_object', Params = {'Bucket': bucket_name, 'Key': key,'ResponseContentType':'image/jpeg', 'ResponseContentDisposition': 'attachment; filename="your-filename.jpeg"'}, ExpiresIn = 1000)

Это в моих настройках:

STATICFILES_LOCATION = 'static'
MEDIAFILES_LOCATION = 'media'
STATICFILES_STORAGE = 'myproject.custom_storages.StaticStorage'
DEFAULT_FILE_STORAGE = 'myproject.custom_storages.MediaStorage'
AWS_ACCESS_KEY_ID = "my_access_key_id"
AWS_SECRET_ACCESS_KEY = "my_secret_access_key"
AWS_STORAGE_BUCKET_NAME = "django-bucket"
AWS_QUERYSTRING_AUTH = False
AWS_S3_CUSTOM_DOMAIN = AWS_STORAGE_BUCKET_NAME + ".s3.amazonaws.com"
# static media settings
STATIC_URL = "https://" + AWS_STORAGE_BUCKET_NAME + ".s3.amazonaws.com/"
MEDIA_URL = STATIC_URL + "media/"
ADMIN_MEDIA_PREFIX = STATIC_URL + "admin/"

Я могу получить путь к файлу изображения

ui = UserImage.objects.get(user=user_id, image=image_id)
url = ui.image.url

'https://django-bucket.s3.amazonaws.com/media/user_image/1497598249_49.jpeg'

Но я не знаю, как получить ключ объекта s3, чтобы я мог сгенерировать URL-адрес для этого объекта.


person Kakar    schedule 17.06.2017    source источник
comment
Этот является URL-адресом объекта. Ведро S3 - это ведро django, а ключ S3 - это media / user_image / 1497598249_49.jpeg.   -  person jarmod    schedule 17.06.2017
comment
@jarmod Да. Но есть ли способ получить это программно, используя пакеты хранения boto3 или django? Или мне следует использовать разделение / замену или какое-то регулярное выражение, чтобы получить его из URL-адреса изображения?   -  person Kakar    schedule 17.06.2017
comment
Почему вы установили AWS_QUERYSTRING_AUTH = False? Быстрая проверка документации показывает, что если для этого параметра установлено значение по умолчанию True, ui.image.url автоматически вернет предварительно подписанный URL-адрес - вам не придется его создавать.   -  person Michael - sqlbot    schedule 17.06.2017
comment
@ Майкл-sqlbot о! Я не знал. Я подумал, что AWS_QUERYSTRING_AUTH = False будет подходящим вариантом, чтобы сделать статические файлы общедоступными. Есть ли способ ответить с этим предварительно подписанным URL-адресом и изменить его заголовки, в основном ContentDisposition и ContentType, чтобы его можно было загрузить? Или надо поменять AWS_QUERYSTRING_AUTH = True, чтобы он заработал?   -  person Kakar    schedule 17.06.2017
comment
Я обнаружил, что хочу получить ключ файла, потому что это, кажется, единственный запрос, существует ли файл на самом деле. Возникла ситуация, когда объекты создавались, но не сохранялись в aws s3.   -  person unlockme    schedule 27.04.2018
comment
Я тоже думал об этом и не нашел выхода. По сути, ключом является имя .name, но оно должно начинаться с префикса «location», установленного для типа хранилища, которое использует объект. Итак, если местоположение - «изображения», .name будет «blabla.jpg», и вам нужно будет вручную указать префикс. .Url делает это автоматически, но есть много причин, по которым вы не хотите получать доступ к S3 по https.   -  person BjornW    schedule 17.06.2019


Ответы (1)


Казалось бы, префикс может быть построен из значения местоположения «хранилище» в поле файла и «имени» файла (которое представляет собой путь от «местоположения» к файлу - он включает в себя то, что большинство из нас считает именем файла. ').

Вот небольшая демонстрация функции, которая должна выполнить свою работу:

import os

def get_file_key(file_field):
    return os.path.join(file_field.storage.location, file_field.name)

Используйте следующим образом:

prefix = get_file_key(my_model_instance.relevant_file_field)

Примечания:

Вы, вероятно, захотите реализовать проверку работоспособности с обнаружением ошибок в / вокруг функции в соответствии с вашими потребностями - например, функция вызовет AttributeError, если file_field имеет значение None - и в большинстве сценариев вы почти наверняка не захотите закончить только с местоположением, если по какой-то причине field.name вернуло пустую строку в результате ошибки или просто потому, что это было каким-то образом сохранено (или '/', если местоположение не было установлено)

person user1936977    schedule 26.11.2019