Как поддерживать несколько групп облачных хранилищ Google в файловом поле Django без нарушения разрешения .url?
Я использую Django с django-storages и серверной частью GoogleCloudStorage.
Моя модель имеет FileField вот такой вид:
raw_file_gcp = models.FileField(storage=GoogleCloudStorage(bucket_name='videos-raw'))
Во время выполнения я копирую файл в другой раздел (например, 'videos-retention'), используя GCS Python SDK:
source_blob = default_bucket.blob(name)
default_bucket.copy_blob(source_blob, retention_bucket, name)
После копирования я обновляю поле .name:
recording.raw_file_gcp.name = f'videos-retention/{name}'
recording.save()
Все работает до тех пор, пока я не перезапущу приложение.
Затем, когда я обращаюсь к .url, Django пытается создать URL-адрес, используя исходный сегмент из аргумента storage=..., даже если файл теперь принадлежит другому сегменту.
Это приводит к созданию недопустимых URL-адресов, таких как:
https://storage.googleapis.com/videos-raw/https%3A/storage.cloud.google.com/videos-retention/filename.mp4
Я ожидал, что Django продолжит работать, даже если файл будет перемещен в другую корзину.
После отладки я понял, что FileField тесно связан с сегментом, используемым при инициализации модели. Если файл перемещается в другой сегмент, .url прерывается.
ChatGPT предложил полностью удалить FileField, вместо этого использовать CharField и динамически разрешать путь к корзине GCS в пользовательском @property с помощью google.cloud.storage.blob.generate_signed_url().
Есть ли лучшее решение для этого?
Как я могу динамически поддерживать несколько групп GCS с помощью Django FileField?
<время работы/>Вместо того, чтобы полагаться на .url, который, казалось бы, был привязан к исходному каталогу GCS, вы можете использовать Google cloud storage SDK для извлечения URL непосредственно из самого хранилища. Метод blob.public_url позволяет сгенерировать допустимый URL-адрес для файла, даже если он был скопирован или перемещен в другую корзину. Однако для личных файлов требуются подписанные URL-адреса, поэтому используйте blob.generate_signed_url в качестве альтернативы.