Django Cloudinary Storage
django-cloudinary-storage is a Django package that provides custom storage backends for Cloudinary, allowing both media and static files to be served from Cloudinary. It also includes management commands for file cleanup. The current version is 0.3.0, released with support for Django 2 and Python 3.6+, with infrequent releases focusing on Django version compatibility.
Common errors
-
ModuleNotFoundError: No module named 'cloudinary_storage'
cause The `django-cloudinary-storage` package is not installed or not accessible in your Python environment.fixRun `pip install django-cloudinary-storage`. -
django.core.exceptions.ImproperlyConfigured: 'cloudinary_storage' is not in your INSTALLED_APPS setting.
cause The `cloudinary_storage` app has not been added to your `INSTALLED_APPS` list in `settings.py`.fixAdd `'cloudinary_storage'` to your `INSTALLED_APPS` list in `settings.py`. -
cloudinary.exceptions.Error: You're not allowed to access this resource
cause Cloudinary was unable to authenticate due to missing or incorrect API credentials (`CLOUDINARY_CLOUD_NAME`, `CLOUDINARY_API_KEY`, `CLOUDINARY_API_SECRET`).fixVerify that your Cloudinary credentials in `settings.py` (or environment variables) are correct and complete. -
AttributeError: 'module' object has no attribute 'MediaCloudinaryStorage'
cause The storage class `MediaCloudinaryStorage` (or `StaticCloudinaryStorage`) was imported from an incorrect path. They reside in the `storage` submodule.fixChange your import statement to `from cloudinary_storage.storage import MediaCloudinaryStorage` (or `StaticCloudinaryStorage`).
Warnings
- gotcha The release notes for v0.3.0 on GitHub contain a typo stating it 'removed Python 3 support'. This is incorrect. Version 0.3.0 and later actually require Python 3.6+ and are compatible with modern Django versions.
- breaking Version 0.3.0 explicitly added support for Django 2.x. If you are using Django 2.x or newer, ensure you are using `django-cloudinary-storage` version 0.3.0 or higher. Older versions may not be compatible.
- gotcha Cloudinary API credentials (`CLOUDINARY_CLOUD_NAME`, `CLOUDINARY_API_KEY`, `CLOUDINARY_API_SECRET`) are mandatory for the storage to authenticate and function correctly. Misconfigured or missing credentials will lead to authentication errors.
- gotcha To ensure Django uses Cloudinary for file uploads, `DEFAULT_FILE_STORAGE` must be set to `'cloudinary_storage.storage.MediaCloudinaryStorage'`. Similarly, for static files, `STATICFILES_STORAGE` should be `'cloudinary_storage.storage.StaticCloudinaryStorage'`.
Install
-
pip install django-cloudinary-storage
Imports
- MediaCloudinaryStorage
from cloudinary_storage import MediaCloudinaryStorage
from cloudinary_storage.storage import MediaCloudinaryStorage
- StaticCloudinaryStorage
from cloudinary_storage import StaticCloudinaryStorage
from cloudinary_storage.storage import StaticCloudinaryStorage
Quickstart
import os
# settings.py
INSTALLED_APPS = [
# ... other Django apps ...
'django.contrib.staticfiles',
'cloudinary_storage',
]
# ... other Django settings (MIDDLEWARE, TEMPLATES, DATABASES, etc.) ...
# Cloudinary Credentials (strongly recommended to use environment variables)
CLOUDINARY_CLOUD_NAME = os.environ.get('CLOUDINARY_CLOUD_NAME', '')
CLOUDINARY_API_KEY = os.environ.get('CLOUDINARY_API_KEY', '')
CLOUDINARY_API_SECRET = os.environ.get('CLOUDINARY_API_SECRET', '')
# Default Storage for Media Files
DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.MediaCloudinaryStorage'
MEDIA_URL = '/media/' # This is still needed for Django's internal URL handling
# Default Storage for Static Files
STATICFILES_STORAGE = 'cloudinary_storage.storage.StaticCloudinaryStorage'
STATIC_URL = '/static/' # This is still needed for Django's internal URL handling
# Optional: Configure prefixing for URLs on Cloudinary (e.g., to group files)
CLOUDINARY_STORAGE = {
'MEDIA_TAG': 'media',
'STATIC_TAG': 'static',
'MEDIA_DELIVERY_URL_WITH_PREFIX': True,
'STATIC_DELIVERY_URL_WITH_PREFIX': True,
'PREFIX': os.environ.get('CLOUDINARY_URL_PREFIX', None), # e.g., 'my_django_project'
}
# Example usage in a model:
# from django.db import models
# class MyPhoto(models.Model):
# title = models.CharField(max_length=100)
# image = models.ImageField(upload_to='photos/%Y/%m/')