Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion edxval/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
init
"""

__version__ = '3.1.0'
__version__ = '3.2.0'
25 changes: 25 additions & 0 deletions edxval/tests/test_storages.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,28 @@ def test_video_transcript_without_storages_settings(self):
'django.core.files.storage.filesystem.FileSystemStorage',
f"{storage_class.__module__}.{storage_class.__name__}",
)

@override_settings(STORAGES={
'video_transcripts': {
'BACKEND': "storages.backends.s3boto3.S3Boto3Storage",
"OPTIONS": {
'bucket_name': 'test',
'default_acl': 'private',
'location': 'abc/'
}
}
}, VIDEO_TRANSCRIPTS_SETTINGS={
'STORAGE_CLASS': 'storages.backends.s3boto3.S3Boto3Storage',
'STORAGE_KWARGS': {
'bucket_name': 'custom-bucket',
'default_acl': 'private',
'location': 'custom/abc/'
}
})
def test_django52_storages_takes_priority_over_custom(self):
#
storage = get_video_transcript_storage()
self.assertIsInstance(storage, S3Boto3Storage)
self.assertEqual(storage.bucket_name, "test")
self.assertEqual(storage.default_acl, 'private')
self.assertEqual(storage.location, 'abc/')
42 changes: 24 additions & 18 deletions edxval/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,25 +153,31 @@ def video_image_path(video_image_instance, filename): # pylint:disable=unused-a
def get_configured_storage(settings_key):
"""
Generic function to return a configured Django storage backend
based on the settings dictionary at `settings_key`. This function falls
back to the `default` storage class if there is no `STORAGE_CLASS` entry
under the `setting_key` object.
based on the settings dictionary at `settings_key`. This function prioritizes
Django 5.2's STORAGES dictionary over custom settings with the same key,
falling back to legacy settings if no STORAGES entry exists.
"""
config = getattr(settings, settings_key, {})
# Retrieve the storage class path and kwargs from the settings
storage_class_path = config.get('STORAGE_CLASS')
options = config.get('STORAGE_KWARGS', {})

# following code only runs for default storages
if not storage_class_path:
storage_class_path = (
getattr(settings, 'DEFAULT_FILE_STORAGE', None) or
getattr(settings, 'STORAGES', {}).get('default', {}).get('BACKEND') or
'django.core.files.storage.FileSystemStorage'
)

# For Django 5.x, pick options if available
options = getattr(settings, 'STORAGES', {}).get('default', {}).get('OPTIONS', {})
storages_config = getattr(settings, 'STORAGES', {})
storage_key = settings_key.replace("_SETTINGS", "")
storage_settings = storages_config.get(storage_key.lower(), {})

if storage_settings:
storage_class_path = storage_settings.get('BACKEND')
options = storage_settings.get('OPTIONS', {})
else:
# Fall back to custom settings configuration
config = getattr(settings, settings_key, {})
storage_class_path = config.get('STORAGE_CLASS')
options = config.get('STORAGE_KWARGS', {})

if not storage_class_path:
storage_class_path = (
storages_config.get('default', {}).get('BACKEND') or
getattr(settings, 'DEFAULT_FILE_STORAGE', None) or
'django.core.files.storage.FileSystemStorage'
)

options = storages_config.get('default', {}).get('OPTIONS', {}) or options

# Import the storage class dynamically
storage_class = import_string(storage_class_path)
Expand Down
Loading