#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 , 10 years ago
comment:2 by , 10 years ago
| Cc: | added |
|---|
comment:3 by , 10 years ago
Configurable file storage backends was already proposed to introduce in terms of task #23251.
comment:4 by , 10 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:5 by , 10 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 , 10 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 , 8 years ago
| Owner: | removed |
|---|---|
| Status: | assigned → new |
comment:8 by , 4 years ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
comment:9 by , 4 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 , 4 years ago
| Has patch: | set |
|---|---|
| Needs tests: | set |
comment:11 by , 3 years ago
| Patch needs improvement: | set |
|---|
comment:14 by , 3 years ago
| Needs tests: | unset |
|---|---|
| Patch needs improvement: | unset |
Unchecked flags, for a new review.
comment:15 by , 3 years ago
| Patch needs improvement: | set |
|---|
PR looks promising, but have comments outstanding ref adding the new STORAGES defaults.
comment:16 by , 3 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:
class Test(Model): a = FileField(storage='myapp.test.a') b = ImageField(storage='myapp.test.b')and then if
myapp.test.aormyapp.test.bwere in the configuration dictionary, they would be used, but if not, andmyapp.testwas, 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, ordefaultetc.) to have finegrained control.