Сохраните загруженное изображение на S3 с помощью Django

Я пытаюсь сохранить изображение на S3 с помощью boto. Он сохраняет файл, но, похоже, не сохраняет его правильно. Если я попытаюсь открыть файл в S3, он просто покажет значок сломанного изображения. Вот код, который я использую:

# Get and verify the file
file = request.FILES['file']
try:
    img = Image.open(file)
except:
    return api.error(400)

# Determine a filename
filename = file.name

# Upload to AWS and register
s3 = boto.connect_s3(aws_access_key_id=settings.AWS_KEY_ID,
                aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY)
bucket = s3.get_bucket(settings.AWS_BUCKET)
f = bucket.new_key(filename)
f.set_contents_from_file(file)

Я также попытался заменить последнюю строку на:

f.set_contents_from_string(file.read())

Но и это не сработало. Есть ли что-то очевидное, что мне здесь не хватает? Я знаю, что у django-storages есть серверная часть boto, но из-за сложности этой модели я не хочу использовать формы с django-storages.


person Luke Sapan    schedule 13.03.2015    source источник


Ответы (2)


Вы должны использовать django-storages, который использует boto для внутреннего использования.

Вы можете либо поменять местами FileSystemStorage по умолчанию, либо создать новый экземпляр хранилища и вручную сохранить файлы. Основываясь на вашем примере кода, я думаю, вы действительно хотите использовать первый вариант.

Пожалуйста, рассмотрите возможность использования Form django вместо прямого доступа к запросу.

person codingjoe    schedule 13.03.2015
comment
На самом деле я собираюсь использовать очень сложную логику, поэтому я решил просто отказаться от форм и хранилищ. Кажется, что это должно быть очень тривиально даже без них. - person Luke Sapan; 13.03.2015
comment
@LukeSapan вам не нужно использовать формы, чтобы использовать хранилище. Просто инициализируйте свое хранилище и используйте save. Я должен посоветовать не использовать boto напрямую, если в этом нет необходимости. - person codingjoe; 13.03.2015
comment
Кстати: если речь идет о сжатии изображений, используйте django-stdimage - person codingjoe; 13.03.2015
comment
Хорошо, я рассмотрю возможность использования django-storage напрямую. И, к сожалению, это не так, это больше о сохранении нескольких типов URL-адресов файлов в столбец, не обязательно все они хранятся в S3. - person Luke Sapan; 13.03.2015
comment
Просто из любопытства, есть ли у вас какие-либо идеи, почему приведенный выше код не работает? - person Luke Sapan; 13.03.2015

Если вы не хотите использовать django-хранилища и просто хотите загрузить несколько файлов на s3, а не все файлы, то ниже приведен код:

import boto3
file = request.FILES['upload']
s3 = boto3.resource('s3', aws_access_key_id=settings.AWS_ACCESS_KEY, aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY)
bucket = s3.Bucket('bucket-name')
bucket.put_object(Key=filename, Body=file)
person Dhruvil Amin    schedule 12.11.2018