Storage¶
The core.storage layer abstracts file storage for the backend.
It provides a single place to define how files are stored and retrieved, while supporting different environments such as:
- local development
- production with S3-compatible object storage
This keeps the rest of the backend independent from storage backend details.
Purpose¶
The storage layer exists to:
- abstract local vs remote storage
- standardize public and private file handling
- keep file access logic out of feature apps
- make storage backend switching configurable
Current Storage Backends¶
The system currently supports two storage modes:
Local filesystem storage¶
Used when:
USE_S3 = False
S3-backed storage¶
Used when:
USE_S3 = Truestoragesis installed
Storage Types¶
The storage layer distinguishes between:
Public storage¶
Files intended to be publicly accessible.
Examples: - public media assets - images intended for direct access
Private storage¶
Files that should not be publicly accessible by default.
Examples: - protected uploads - restricted documents - internal attachments
Storage Resolution¶
Storage backend selection is performed dynamically.
The helper:
use_s3()
determines whether S3-backed storage should be used.
Then the factory helpers choose the correct implementation:
public_storage()private_storage()
Public Storage¶
Local Public Storage¶
Local public storage uses a filesystem location under:
MEDIA_ROOT/public
Its base URL is derived from:
MEDIA_URL/public/
This is intended for development and simple deployments.
S3 Public Storage¶
S3 public storage uses:
- location =
public - public-read ACL
- unsigned URLs
This is appropriate for assets that can be served directly.
Private Storage¶
Local Private Storage¶
Local private storage uses a filesystem location under:
MEDIA_ROOT/private
It does not expose a base URL directly.
This helps keep private files separate from public media.
S3 Private Storage¶
S3 private storage uses:
- location =
private - private ACL
- signed URLs
This allows protected files to be served securely without making the bucket or object public.
Storage Selection Flow¶
flowchart TD
A[Need storage backend] --> B{USE_S3?}
B -->|No| C[Local Storage]
B -->|Yes| D[S3 Storage]
C --> E[Public or Private]
D --> E
¶
flowchart TD
A[Need storage backend] --> B{USE_S3?}
B -->|No| C[Local Storage]
B -->|Yes| D[S3 Storage]
C --> E[Public or Private]
D --> E
Main Helpers¶
use_s3()¶
Returns whether the system should use S3-backed storage.
This is controlled by Django settings.
public_storage()¶
Returns the configured public storage backend.
Possible result: - LocalPublicMediaStorage - S3PublicMediaStorage
private_storage()¶
Returns the configured private storage backend.
Possible result: - LocalPrivateMediaStorage - S3PrivateMediaStorage
Why This Abstraction Matters¶
Without a storage abstraction, feature apps would need to know: - where files are stored - how URLs are generated - whether storage is local or remote - whether files are public or private
The storage layer hides all of that behind a consistent API.
Relationship to Other Layers¶
Upload validation¶
Handled separately in: - uploads.md
Download access¶
If private downloads are introduced later, feature-specific access control should sit above the storage layer.
The storage layer only determines where files live, not who may access them.
Configuration Expectations¶
The storage layer depends on settings such as: - USE_S3 - MEDIA_ROOT - MEDIA_URL - installed app storages
S3-specific configuration should also be provided when S3 mode is enabled.
Design Principles¶
The storage layer is designed to be: - environment-aware - simple to switch - explicit about public vs private files - reusable across all apps
What Storage Should NOT Do¶
The storage layer should not: - perform permission checks - validate business rules - decide whether a file upload is allowed - implement feature-specific download behavior
Those concerns belong elsewhere.
Typical Usage¶
Feature apps should use: - public_storage() for public file fields - private_storage() for restricted file fields
This avoids hardcoding backend-specific storage classes inside feature code.
Future Extensions¶
The storage layer can later be extended with: - CDN-specific integration - file lifecycle policies - storage usage metrics - file expiration strategies - region-aware storage routing
Summary¶
The core.storage layer provides a centralized abstraction for file storage.
It ensures that: - storage backend choice is configurable - public and private files are clearly separated - feature apps remain independent from storage details