Opened 38 hours ago
Closed 36 hours ago
#36824 closed New feature (wontfix)
FileField storage parameter should support string references to STORAGES dict keys
| Reported by: | Petr Dlouhý | Owned by: | |
|---|---|---|---|
| Component: | File uploads/storage | Version: | 6.0 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Summary
FileField's storage parameter doesn't support string references to STORAGES dict keys, despite Django 4.2+ establishing STORAGES as the standard configuration method. This creates confusion and forces workarounds.
Description
Django 4.2 introduced the STORAGES setting as a centralized dictionary for configuring storage backends, deprecating DEFAULT_FILE_STORAGE. However, FileField and ImageField don't support string references to these storage keys.
Current Behavior
# settings.py STORAGES = { "default": {...}, "private_assets": {...}, } # models.py from django.core.files.storage import storages # This works - but verbose and requires callable wrapper def get_private_storage(): return storages["private_assets"] class MyModel(models.Model): file = models.FileField(storage=get_private_storage)
Expected Behavior
# This should work - consistent with STORAGES design class MyModel(models.Model): file = models.FileField(storage="private_assets")
Problem
When developers try the intuitive approach (storage="private_assets"), Django stores it as a string. This fails silently until runtime when code accesses field.storage, causing:
AttributeError: 'str' object has no attribute 'path'
This is particularly problematic for third-party libraries (like easy-thumbnails) that access field.storage directly and expect a storage object, not a string.
Inconsistency
The STORAGES dict uses string keys everywhere:
- ✅
settings.STORAGES["default"]- configuration - ✅
storages["private_assets"]- runtime access - ✅
THUMBNAIL_DEFAULT_STORAGE = "thumbnails"- library settings - ❌
FileField(storage="name")- doesn't work
This breaks the principle of least surprise. If Django establishes a pattern (string keys for storage), it should work consistently across the framework.
Real-World Impact
I encountered this while implementing Django STORAGES support for easy-thumbnails. Users naturally try storage="name" based on the STORAGES pattern, and it fails with a cryptic error. This forced me to add defensive string resolution in the library.
Proposed Solutions
Option A: Support string storage in FileField (Recommended)
Add string resolution in FileField.__init__():
def __init__(self, ..., storage=None, **kwargs): self.storage = storage or default_storage # Resolve string references to STORAGES dict if isinstance(self.storage, str): from django.core.files.storage import storages self.storage = storages[self.storage] if callable(self.storage): self._storage_callable = self.storage self.storage = self.storage() ...
Benefits:
- Consistent with STORAGES design
- Intuitive for developers
- Backwards compatible (no breaking changes)
- ~5 lines of code
Option B: Document that string storage is not supported
If supporting string storage is not desired, clearly document in FileField docs:
Note: The storage parameter does not support string references to STORAGES dict keys.
Use a callable function to reference configured storages:
def get_my_storage():
from django.core.files.storage import storages
return storages["my_storage"]
file = models.FileField(storage=get_my_storage)
This at least prevents confusion and provides a clear workaround.
Migration Behavior
String storage resolution wouldn't create migration issues because:
- Strings would be resolved at model load time (like callables)
- Migrations would store the string reference, not the resolved object
- This mirrors how callable storage already works
Backwards Compatibility
Fully backwards compatible - existing code using storage objects or callables continues working unchanged.
Related Tickets
- #31941 - FileField with callable storage deconstruction
- #34192 - Callable storage returning default_storage
Questions
- Was excluding string storage from FileField intentional, or an oversight during STORAGES implementation?
- If intentional, what's the reasoning? (I'd like to understand the design decision)
- If not desired as a feature, can we at least improve documentation to prevent this confusion?
Change History (1)
comment:1 by , 36 hours ago
| Component: | Uncategorized → File uploads/storage |
|---|---|
| Resolution: | → wontfix |
| Status: | new → closed |
Replying to Petr Dlouhý:
Hello Petr! The
storageoption works exactly as described in the docs:When suggesting a new feature for Django, the feature should first be proposed and discussed with the community. To do that, please raise this on the new feature tracker where you'll receive feedback from the community.
I'll close the ticket for now, but if the community agrees with the proposal, please return to this ticket and reference the feature discussion so we can re-open it. For more information, please refer to the documented guidelines for requesting features.
Lastly, please avoid using LLM to generate overly verbose reports.