Storage Utilities¶
DRF Toolkit provides storage utilities to help manage file storage paths and naming conventions in your Django applications.
BaseDataStoragePath¶
The BaseDataStoragePath
class provides utilities for handling file storage paths and file naming. It's particularly useful when you need consistent file naming conventions and unique file paths in your storage system.
Features¶
- Automatic unique file naming using UUID
- File extension handling
- Flexible path building
- Support for both model instances and dictionaries
Basic Usage¶
from drf_kit.storage import BaseDataStoragePath
# Rename a file with unique suffix
new_filename = BaseDataStoragePath.rename(
filename="document.pdf",
unique=True
)
# Result: document_550e8400-e29b-41d4-a716-446655440000.pdf
# Rename with custom name
new_filename = BaseDataStoragePath.rename(
filename="document.pdf",
new_name="contract",
unique=True
)
# Result: contract_550e8400-e29b-41d4-a716-446655440000.pdf
File Extension Handling¶
The class handles file extensions intelligently:
# With existing extension
filename = BaseDataStoragePath.rename(
filename="document.pdf",
new_name="contract"
)
# Result: contract.pdf
# With default extension
filename = BaseDataStoragePath.rename(
filename="document",
new_name="contract",
default_extension="txt"
)
# Result: contract.txt
# Without extension
filename = BaseDataStoragePath.rename(
filename="document",
new_name="contract"
)
# Result: contract (with warning log)
Custom Storage Path¶
You can extend the class for custom storage paths:
class UserAvatarStorage(BaseDataStoragePath):
@classmethod
def get_upload_path(cls, instance, filename):
user_id = cls._get_pk(instance)
new_filename = cls.rename(filename, unique=True)
return f"avatars/{user_id}/{new_filename}"
# Usage with model
class UserProfile(models.Model):
avatar = models.ImageField(
upload_to=UserAvatarStorage.get_upload_path
)
Primary Key Handling¶
The class handles primary keys for both model instances and dictionaries:
# With model instance
profile = UserProfile.objects.get(id=1)
pk = BaseDataStoragePath._get_pk(profile) # Returns "1"
# With dictionary
data = {"id": "123"}
pk = BaseDataStoragePath._get_pk(data) # Returns "123"
# With new instance (generates UUID)
new_profile = UserProfile()
pk = BaseDataStoragePath._get_pk(new_profile) # Returns UUID string
Best Practices¶
- Use unique filenames when storing user-uploaded files to prevent collisions
- Create custom storage classes for different types of files (e.g., avatars, documents)
- Always handle file extensions appropriately
- Consider implementing cleanup methods for old files
- Use the storage utilities with Django's file fields for consistent handling