Как поддерживать несколько групп облачных хранилищ 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 в качестве альтернативы.

Вернуться на верх