Collectfast: A Faster Collectstatic for Django
Collectfast dramatically speeds up Django's `collectstatic` command when using cloud storage by only uploading static files that have changed. It leverages MD5 hashes (ETags) or modification times to determine if a file needs to be re-uploaded. The current version is 2.2.0, with a release cadence of a few times per year, focusing on compatibility and performance improvements.
Common errors
-
ModuleNotFoundError: No module named 'collectfast'
cause The `collectfast` package is not installed in the active Python environment.fixRun `pip install collectfast` to install the package. -
ImproperlyConfigured: COLLECTFAST_STRATEGY setting is required.
cause Since version 2.0.0, collectfast requires an explicit strategy to be set, as automatic guessing was removed.fixAdd `COLLECTFAST_STRATEGY = 'collectfast.strategies.aws.S3Strategy'` (or the appropriate strategy for your setup) to your Django `settings.py`. -
ImproperlyConfigured: collectfast doesn't support your storage backend
cause The `STATICFILES_STORAGE` backend you have configured either does not have a corresponding `collectfast` strategy, or `COLLECTFAST_STRATEGY` is incorrectly configured for it.fixEnsure `STATICFILES_STORAGE` is set to a supported backend (e.g., `storages.backends.s3boto3.S3Boto3Storage`) and `COLLECTFAST_STRATEGY` is correctly configured for it (e.g., `'collectfast.strategies.aws.S3Strategy'` for S3). -
AttributeError: 'S3BotoStorage' object has no attribute 'bucket_name' (or similar errors related to `boto`)
cause This typically occurs when using the older `storages.backends.s3boto.S3BotoStorage` with `collectfast` 2.0.0+, which removed support for the `boto` library and its associated strategy.fixMigrate your `STATICFILES_STORAGE` to `storages.backends.s3boto3.S3Boto3Storage` and update `COLLECTFAST_STRATEGY` to `collectfast.strategies.aws.S3Strategy` to use `boto3`.
Warnings
- breaking `collectfast` 2.0.0 dropped support for Python 3.5 and Django 1.11. It also removed the `boto` strategy (`collectfast.strategies.boto.BotoStrategy`), requiring migration to `boto3` strategies for S3.
- breaking Starting with `collectfast` 2.0.0, the `COLLECTFAST_STRATEGY` setting must be explicitly defined in your Django `settings.py` as automatic strategy guessing was removed.
- deprecated `collectfast.strategies.boto.BotoStrategy` was deprecated in version 1.3.0 and completely removed in 2.0.0. Using this strategy will result in errors.
- gotcha Prior to `collectfast` 2.2.0, there was a bug where gzip compression level for static files was inconsistent with S3's default handling, potentially causing issues with served content if not explicitly managed.
Install
-
pip install collectfast
Imports
- Strategy
from collectfast.strategies.base import Strategy
Quickstart
import os
# settings.py
# Add collectfast to your INSTALLED_APPS
INSTALLED_APPS = [
# ... other apps
'collectfast',
'storages', # if using django-storages
]
# Enable Collectfast
COLLECTFAST_ENABLED = True
# Explicitly set the strategy (required since collectfast 2.0.0)
# Choose the strategy that matches your STATICFILES_STORAGE backend
# For AWS S3 with django-storages s3boto3 backend:
COLLECTFAST_STRATEGY = 'collectfast.strategies.aws.S3Strategy'
# Configure your STATICFILES_STORAGE (example for AWS S3 with django-storages)
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID', 'your_access_key')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY', 'your_secret_key')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME', 'your-bucket-name')
AWS_S3_REGION_NAME = os.environ.get('AWS_S3_REGION_NAME', 'us-east-1')
AWS_S3_SIGNATURE_VERSION = 's3v4'
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None # Or 'public-read' if files should be publicly accessible
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/"
# Define STATIC_ROOT for local collectstatic (even if collectfast bypasses it for cloud storage)
STATIC_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'staticfiles')