From 6e264b14803bde4721fe68888f8fbaff74b2fcbb Mon Sep 17 00:00:00 2001 From: Lorenz Padberg Date: Wed, 17 May 2023 18:00:41 +0200 Subject: [PATCH] Add azure blob storage to django --- env_secrets/production_azure.env | Bin 2612 -> 2887 bytes server/backend/__init__.py | 0 server/backend/custom_azure.py | 18 ++++++++++++++++++ server/config/settings/base.py | 14 ++++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 server/backend/__init__.py create mode 100644 server/backend/custom_azure.py diff --git a/env_secrets/production_azure.env b/env_secrets/production_azure.env index 46a2267331a58cc9d8885666dde9eedf783e6557..a6c56c0b6d2b365e6227609961ed86309b809f59 100644 GIT binary patch literal 2887 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 literal 2612 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 W^Bf4YkXbDkL=5M5*$lbrZ;c^Lk{VqA diff --git a/server/backend/__init__.py b/server/backend/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/backend/custom_azure.py b/server/backend/custom_azure.py new file mode 100644 index 00000000..fe0c9b08 --- /dev/null +++ b/server/backend/custom_azure.py @@ -0,0 +1,18 @@ + +from storages.backends.azure_storage import AzureStorage +from environs import Env + +env = Env() +env.read_env() +class AzureMediaStorage(AzureStorage): + account_name = env("AZURE_STORAGE_ACCOUNT") + account_key = env("AZURE_STORAGE_KEY") + azure_container = 'media' + expiration_secs = None + +class AzureStaticStorage(AzureStorage): + account_name = env("AZURE_STORAGE_ACCOUNT") + account_key = env("AZURE_STORAGE_KEY") + azure_container = 'static' + expiration_secs = None + diff --git a/server/config/settings/base.py b/server/config/settings/base.py index 7cfba7f1..3fc03441 100644 --- a/server/config/settings/base.py +++ b/server/config/settings/base.py @@ -214,6 +214,20 @@ if USE_AWS: # https://wagtail.org/blog/amazon-s3-for-media-files/ MEDIA_URL = "https://%s/" % AWS_S3_CUSTOM_DOMAIN DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" +elif env(USE_AZURE_BLOB_STORAGE): + # https://medium.com/@DawlysD/django-using-azure-blob-storage-to-handle-static-media-assets-from-scratch-90cbbc7d56be + DEFAULT_FILE_STORAGE = 'backend.custom_azure.AzureMediaStorage' + STATICFILES_STORAGE = 'backend.custom_azure.AzureStaticStorage' + + STATIC_LOCATION = "static" + MEDIA_LOCATION = "media" + + AZURE_ACCOUNT_NAME = "djangoaccountstorage" + AZURE_CUSTOM_DOMAIN = f'{AZURE_ACCOUNT_NAME}.blob.core.windows.net' + STATIC_URL = f'https://{AZURE_CUSTOM_DOMAIN}/{STATIC_LOCATION}/' + MEDIA_URL = f'https://{AZURE_CUSTOM_DOMAIN}/{MEDIA_LOCATION}/' + + else: MEDIA_URL = "/server/media/"