#26029 closed New feature (fixed)
Provide an API to configure arbitrary file storage backends
Reported by: | Aymeric Augustin | Owned by: | Jarosław Wygoda |
---|---|---|---|
Component: | File uploads/storage | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | django@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Currently Django has two hardcoded file storage backends, "default" (for media files) and "static" (for static files). Idioms for configuring file storage backends in pluggable apps are cumbersome.
It would be nice to be able to configure arbitrary file storage backends, like caches and databases e.g.:
FILE_STORAGES = { 'media': { 'BACKEND': settings.DEFAULT_FILE_STORAGE, 'OPTIONS': { 'location': settings.MEDIA_ROOT, 'base_url': settings.MEDIA_URL, # possible override of settings.FILE_CHARSET }, }, 'static': { 'BACKEND': settings.STATICFILES_STORAGE, 'OPTIONS': { 'location': settings.STATIC_ROOT, 'base_url': settings.STATIC_URL, # replacement for STATICFILES_FINDERS and STATICFILES_DIRS that would look a lot like template loaders # possible override of settings.FILE_CHARSET }, }
This was discussed on django-developers: https://groups.google.com/d/msg/django-developers/gEbFApLLuzg/IW1LDUwmEgAJ
There were some concerns about introducing another large dict in settings. The general ideas was uncontroversial.
Change History (24)
comment:1 by , 9 years ago
comment:2 by , 9 years ago
Cc: | added |
---|
comment:3 by , 9 years ago
Configurable file storage backends was already proposed to introduce in terms of task #23251.
comment:4 by , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:5 by , 9 years ago
Replying to aaugustin:
FILE_STORAGES = { 'media': { 'BACKEND': settings.DEFAULT_FILE_STORAGE, 'OPTIONS': { 'location': settings.MEDIA_ROOT, 'base_url': settings.MEDIA_URL, # possible override of settings.FILE_CHARSET }, ... }
Media backend will have media
key in settings, not default
, to keep it consistent with the current settings?
comment:6 by , 9 years ago
As proposed Aymeric Augustin in the original PR, I started to compose DEP, so now it's in progress and I hope to finish it sometime soon.
comment:7 by , 7 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
comment:8 by , 3 years ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:9 by , 3 years ago
I'd like to introduce a file storage registry similar to BaseConnectionHandler (django/utils/connection.py) and EngineHandler (django/template/utils.py).
Example settings.py snippet:
STORAGES = { # rename to FILE_STORAGES to make it more explictit? 'example': { 'BACKEND': 'django.core.files.storage.FileSystemStorage', 'OPTIONS': { 'location': '/example', 'base_url': '/example/', }, }, }
Changes introduced by this pr are backward compatible. Users can still use existing settings to configure static and media storages.
Currently storages can be retrieved from the following objects:
django/core/files/storage.py:
- get_storage_class
- DefaultStorage
- default_storage
django/contrib/staticfiles/storage.py:
- ConfiguredStorage
- staticfiles_storage
What do you think about deprecating them?
I'll write tests and docs if this approach is acceptable.
comment:10 by , 3 years ago
Has patch: | set |
---|---|
Needs tests: | set |
comment:11 by , 2 years ago
Patch needs improvement: | set |
---|
comment:14 by , 2 years ago
Needs tests: | unset |
---|---|
Patch needs improvement: | unset |
Unchecked flags, for a new review.
comment:15 by , 2 years ago
Patch needs improvement: | set |
---|
PR looks promising, but have comments outstanding ref adding the new STORAGES
defaults.
comment:16 by , 2 years ago
Patch needs improvement: | unset |
---|
I think the PR looks close. (I suggested a few docs tweaks)
Main remaining point (for me) is being sure about the signal handling with override_settings
, and the usual Settings
/UserSettingsHolder
complexities.
For what it's worth, bmispelon and I discussed something akin to this recently, out of which I started implementing something similar entirely as an experiment. One thing I liked about where I went with that was that a named storage key in the dictionary was a dotted path, and behaved somewhat like a logging config in that the nearest 'parent' match such that each model field which uses a storage could be addressed separately, like so:
and then if
myapp.test.a
ormyapp.test.b
were in the configuration dictionary, they would be used, but if not, andmyapp.test
was, that would be used, and so on walking backwards up the dotted path (falling back to ostensiblydefault
[''
] in the end)The notion there was third-party apps could namespacing storages per-field, but at a project level one only has to opt-in as much as one cares (ie:
myapp
, ormyapp.test
, ordefault
etc.) to have finegrained control.