File Models¶
The File Models in DRF Toolkit provide enhanced file handling capabilities for Django models. The functionality is implemented through the BoundedFileMixin
, which is included in BaseModel
.
BoundedFileMixin¶
The BoundedFileMixin
automatically manages file names and storage operations for models with file fields.
from drf_kit.models import BaseModel
class Document(BaseModel): # Includes BoundedFileMixin
file = models.FileField(upload_to='documents/')
title = models.CharField(max_length=100)
Features¶
- Automatic file name management
- Support for custom storage backends
- Efficient file operations
- Proper file cleanup
- Handles multiple file fields
File Management¶
The mixin manages files during model creation:
- Generates proper file names using the field's
upload_to
and file name generator - Moves files to their final location
- Updates file references in the model
- Handles cleanup of temporary files
Storage Backend Support¶
The mixin works with different storage backends:
class Document(BaseModel):
# Local filesystem storage
local_file = models.FileField(
upload_to='local/',
storage=FileSystemStorage()
)
# Custom storage backend
cloud_file = models.FileField(
upload_to='cloud/',
storage=CustomStorageBackend()
)
Storage Operations¶
- Uses
move
operation when available (more efficient) - Falls back to save/delete for basic storage backends
- Properly closes file handles after operations
Usage Examples¶
Basic File Handling¶
class UserDocument(BaseModel):
file = models.FileField(upload_to='user_docs/')
user = models.ForeignKey(User, on_delete=models.CASCADE)
# File will be automatically managed
doc = UserDocument.objects.create(
file=uploaded_file,
user=user
)
Custom File Naming¶
def generate_filename(instance, filename):
return f"documents/{instance.user.id}/{filename}"
class Document(BaseModel):
file = models.FileField(upload_to=generate_filename)
Multiple File Fields¶
class MediaItem(BaseModel):
image = models.ImageField(upload_to='images/')
document = models.FileField(upload_to='documents/')
attachment = models.FileField(upload_to='attachments/')
# All files will be properly managed
Custom Storage Backend¶
class S3Document(BaseModel):
file = models.FileField(
upload_to='documents/',
storage=S3Boto3Storage()
)
# Files will be efficiently moved in S3
# if the storage backend supports move operations
Best Practices¶
- Always use the mixin (through BaseModel) when working with file fields
- Implement proper file name generators for organized storage
- Use storage backends that support move operations for better performance
- Consider implementing file cleanup on model deletion if needed
- Handle file operations in transactions when appropriate
Technical Details¶
File Operations¶
The mixin performs these steps during model creation:
- Saves the model instance first
- Identifies all FileField instances
- For each file:
- Generates the final filename
- Moves/copies the file if needed
- Updates the file reference
- Saves the model again if files were modified
Storage Backend Integration¶
# With move support
if hasattr(file.storage, "move"):
file.storage.move(old_file, new_file)
else:
# Fallback for basic storage
file.storage.save(new_file, file)
file.storage.delete(old_file)
This ensures compatibility with both simple and advanced storage backends.