-
Notifications
You must be signed in to change notification settings - Fork 81
fix: Django52 use STORAGES instead of DEFAULT_FILE_STORAGE and STATICFILES_STORAGE #2844
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Django52 use STORAGES instead of DEFAULT_FILE_STORAGE and STATICFILES_STORAGE #2844
Conversation
bfc5722 to
029594a
Compare
|
is this different from #2828 which has a pending question on it? |
d14cbac to
7cd09bf
Compare
Yes this is actual one |
9733674 to
10baf35
Compare
|
@wgu-ram-chandra Please review this PR. |
10baf35 to
29560aa
Compare
…FILES_STORAGE Depriciate STATICFILES_STORAGE and DEFAULT_FILE_STORAGE, and use STORAGE in Django 5.2
29560aa to
7ab9ce3
Compare
|
this is awaiting review from @wgu-ram-chandra, but also, I assume that this one should not be merged until all of the pending requests have been resolved on the related PR openedx/edx-platform#37002, because any related issues should presumably be addressed here as well. |
|
@deborahgu Yes we are following that as well |
|
Hi @awais786 @deborahgu, sorry for the delay. I'll review it today! |
wgu-ram-chandra
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mubbsharanwar Thanks for the PR! I’ve left a few comments, once those are addressed, I’ll be happy to take another look.
credentials/settings/devstack.py
Outdated
| EMAIL_FILE_PATH = "/tmp/credentials-emails" | ||
|
|
||
| DEFAULT_FILE_STORAGE = os.environ.get("DEFAULT_FILE_STORAGE", "django.core.files.storage.FileSystemStorage") | ||
| STORAGES["default"]["BACKEND"] = os.environ.get( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
os.environ.get() expects an environment variable name, but the current code passes the backend value instead. This ends up looking for an env var like "django.core.files.storage.FileSystemStorage", which won’t exist, so it always falls back to the default and the override never takes effect.
We could assign django.core.files.storage.FileSystemStorage directly, or alternatively read from DEFAULT_FILE_STORAGE and assign that to maintain backward compatibility.
credentials/settings/devstack.py
Outdated
| MEDIA_URL = os.environ.get("MEDIA_URL", "/media/") | ||
|
|
||
| STATICFILES_STORAGE = os.environ.get("STATICFILES_STORAGE", "django.contrib.staticfiles.storage.StaticFilesStorage") | ||
| STORAGES["staticfiles"]["BACKEND"] = "django.contrib.staticfiles.storage.StaticFilesStorage" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here! We could assign django.contrib.staticfiles.storage.StaticFilesStorage directly, or alternatively read from STATICFILES_STORAGE and assign for backward compatibility.
credentials/settings/production.py
Outdated
|
|
||
| if "DEFAULT_FILE_STORAGE" in config_from_yaml: | ||
| STORAGES["default"] = {"BACKEND": config_from_yaml.pop("DEFAULT_FILE_STORAGE")} | ||
| vars().update(STORAGES) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using vars().update(STORAGES) can be risky because it flattens nested dictionaries into module-level variables like default and staticfiles, which is undesirable. It’s preferable to update the STORAGES dictionary directly rather than modifying vars().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mubbsharanwar it looks like this is still unaddressed.
credentials/settings/production.py
Outdated
|
|
||
| vars().update(config_from_yaml) | ||
|
|
||
| if "DEFAULT_FILE_STORAGE" in FILE_STORAGE_BACKEND: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point, it’s not obvious what structure FILE_STORAGE_BACKEND takes, it’s initialized as {} and later populated from CREDENTIALS_CFG. The if "DEFAULT_FILE_STORAGE" logic seems to assume it’s a flat dict with backend paths as values. Could you confirm whether that assumption is correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that assumption is correct. DEFAULT_FILE_STORAGE is a flat dict.
credentials/settings/test.py
Outdated
| # Local Directories | ||
| TEST_ROOT = path("test_root") | ||
| DEFAULT_FILE_STORAGE = "django.core.files.storage.FileSystemStorage" | ||
| STORAGES["default"]["BACKEND"] = os.environ.get( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as noted above in credentials/settings/devstack.py, this also applies to the old keys here.
c919ce7 to
54e6d0f
Compare
|
Could you get review from a maintainer instead? |
|
@deborahgu Please review this PR. |
|
@deborahgu Please wait let me verify one thing. |
|
@deborahgu I just verified using this yaml So the django shell showing following output Observation:
wrong behaviour This is the root cause. |
|
I don't have the domain knowledge but you can comment or test this PR as it is. If purpose is only to set |
credentials/settings/production.py
Outdated
|
|
||
| if "DEFAULT_FILE_STORAGE" in config_from_yaml: | ||
| STORAGES["default"] = {"BACKEND": config_from_yaml.pop("DEFAULT_FILE_STORAGE")} | ||
| vars().update(STORAGES) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mubbsharanwar it looks like this is still unaddressed.
credentials/settings/production.py
Outdated
| vars().update(FILE_STORAGE_BACKEND) | ||
| if "DEFAULT_FILE_STORAGE" in FILE_STORAGE_BACKEND: | ||
| default_file_storage = FILE_STORAGE_BACKEND.pop("DEFAULT_FILE_STORAGE") | ||
| vars().update(FILE_STORAGE_BACKEND) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mubbsharanwar I think the bug is here. By running this vars().update(FILE_STORAGE_BACKEND) won't this will take the keys and values inside that dict and drop it at the top level of the settings dict? Is that the intention?
@deborahgu it looks like FILE_STORAGE_BACKEND is not a django notion but something we may have invented in our settings. Is this being used in credentials settings? How is it structured? I don't see any references to it in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@feanil I’ll fix it now; I just needed some clarification on the expected behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@feanil I think I got the issue. I will fix both the PRs in credentials and disco.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sample yaml
FILE_STORAGE_BACKEND
AWS_STORAGE_BUCKET_NAME: stage-edx-catalog
DEFAULT_FILE_STORAGE: storages.backends.s3boto3.S3Boto3Storage1234
All the keys from FILE_STORAGE_BACKEND are promoted to the root-level Django settings.
As soon as DEFAULT_FILE_STORAGE is set, Django automatically updates the STORAGES dict to reflect it.
IN django==4.2.24 you see this.
>>> from django.conf import settings
>>> settings.STORAGES
{'default': {'BACKEND': 'storages.backends.s3boto3.S3Boto3Storage1234'}, 'staticfiles': {'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage'}}
>>> settings.DEFAULT_FILE_STORAGE
'storages.backends.s3boto3.S3Boto3Storage1234'
So, setting DEFAULT_FILE_STORAGE directly ensures both DEFAULT_FILE_STORAGE and STORAGES['default'] stay in sync.
But for django52 we need to do this explicitly. So code is working due the root values set in production.
feat!: fixing storages.
feat!: fixing storages.
feat!: fixing inline comment.
|
@feanil @deborahgu Please review now. |
credentials/settings/base.py
Outdated
| "STORAGES": { | ||
| "default": {"BACKEND": STORAGES["default"]["BACKEND"]}, | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "STORAGES": { | |
| "default": {"BACKEND": STORAGES["default"]["BACKEND"]}, | |
| }, | |
| "STORAGES": STORAGES |
credentials/settings/devstack.py
Outdated
| STORAGES = { | ||
| "default": { | ||
| "BACKEND": "django.core.files.storage.FileSystemStorage", | ||
| }, | ||
| "staticfiles": { | ||
| "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage", | ||
| }, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to redefine STORAGES, its coming from base.py
| EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend" | ||
| EMAIL_FILE_PATH = "/tmp/credentials-emails" | ||
|
|
||
| DEFAULT_FILE_STORAGE = os.environ.get("DEFAULT_FILE_STORAGE", "django.core.files.storage.FileSystemStorage") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defaultfile_storage = os.environ.get("DEFAULT_FILE_STORAGE", "django.core.files.storage.FileSystemStorage")
if defaultfile_storage:
STORAGES["default"]["BACKEND"] = defaultfile_storage| }, | ||
| } | ||
|
|
||
| STATICFILES_STORAGE = os.environ.get("STATICFILES_STORAGE", "django.contrib.staticfiles.storage.StaticFilesStorage") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
staticfiles_storage = os.environ.get('STATICFILES_STORAGE', 'django.contrib.staticfiles.storage.StaticFilesStorage')
if staticfiles_storage:
STORAGES["staticfiles"]["BACKEND"] = staticfiles_storage
credentials/settings/test.py
Outdated
|
|
||
| STORAGES = { | ||
| "default": { | ||
| "BACKEND": "django.core.files.storage.FileSystemStorage", | ||
| }, | ||
| "staticfiles": { | ||
| "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage", | ||
| }, | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to redefine the STORAGES
feat!: fixing inline comment.
feat!: fixing inline comment.
|
@feanil its ready now. |
|
Looks good, I'll do a final review and merge on Monday. |
|
For tracking purpose. |
Don't set defaults when that are the same as the defaults from base.py setting them in multiple places could lead to confusion and bugs in the future.
Description
Depreciate
STATICFILES_STORAGEandDEFAULT_FILE_STORAGE, and useSTORAGEto upgrade edx-platform to Django 5.2