Предварительно подписанный URL с boto3 и django-storages неверный путь к файлу
Для функции загрузки файлов я пытаюсь установить FileField
в Django, используя предварительно заданный url, но когда поле сохраняется, кажется, что имя aws bucket добавляется в url, поэтому, когда я пытаюсь получить доступ к файлу из админки django, я получаю Key does not exist
ошибку.
Для загрузки я сначала генерирую предварительно назначенный url на бэкенде:
try:
s3_client = boto3.client(
"s3",
region_name=settings.AWS_S3_REGION_NAME,
config=Config(signature_version="s3v4"),
aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
)
s3_response = s3_client.generate_presigned_url(
"put_object",
HttpMethod="PUT",
ExpiresIn=settings.AWS_SIGNED_URL_DURATION,
Params={
"Bucket": settings.AWS_STORAGE_BUCKET_NAME,
"Key": f"{user.uuid}/{instance.uuid}/{payload.dict().get('filename')}",
"ContentType": "application/octet-stream",
},
)
except ClientError as e:
logger.exception(e)
return 500, {"message": "Something went wrong."}
Затем это используется фронтенд-клиентом для загрузки файла - все работает нормально и загружает файл по следующему url:
https://<BUCKET_NAME>.s3.<BUCKET_REGION>.amazonaws.com/<USER_UUID>/<INSTANCE_UUID>/<FILE_NAME>
(я проверил в s3 и файл там)
Затем фронтенд отправляет запрос на обновление БД с url после успешной загрузки. Данные выглядят следующим образом:
{"file_field": "<USER_UUID>/<INSTANCE_UUID>/<FILE_NAME>"}
Однако, когда я пытаюсь получить доступ к файлу из админки django (или когда я получаю данные экземпляра из моего REST API), поле файла показывает другой url:
https://<BUCKET_NAME>.s3.<BUCKET_REGION>.amazonaws.com/<BUCKET_NAME>/<USER_UUID>/<INSTANCE_UUID>/<FILE_NAME>
(Обратите внимание на лишнюю BUCKET_NAME
после amazonaws.com/
.
Я не могу понять, откуда взялась эта дополнительная BUCKET_NAME
- мне кажется, что я упускаю что-то очевидное! Любая помощь будет очень признательна, спасибо!
Согласно этому обсуждению на github, установка AWS_S3_ADDRESSING_STYLE
в virtual
и AWS_S3_ENDPOINT_URL
в https://s3.amazonaws.com
приведет к добавлению имени bucket к url и не будет включать его в путь url.
Эй, я уверен, что это связано с переменной AWS_S3_ADDRESSING_STYLE. Если установить эту переменную в виртуальное значение и задать для AWS_S3_ENDPOINT_URL значение https://s3.amazonaws.com, то имя вашего ведра будет автоматически добавлено к конечной точке и не будет добавляться в путь URL.