A step-by-step guide to configuring Django 5 to store static and media files on Cloudflare R2, an S3-compatible object storage with zero egress fees and a generous free tier (10 GB storage, 1M writes/month, 10M reads/month). Covers creating public and private R2 buckets, generating API tokens, and wiring up django-storages with the S3Boto3Storage backend. Demonstrates separate storage classes for public files (served via public URL) and private files (protected with signed S3v4 URLs). Also notes R2 limitations compared to AWS S3: no versioning, only bucket-level access controls, and weak analytics.
Table of contents
ContentsProject SetupCloudflare BucketCloudflare API TokenDjango StoragesStatic FilesMedia FilesTestingWrapping UpQuestions this post answers
How do I use Cloudflare R2 for Django static and media files with django-storages?
Use django-storages with the S3Boto3Storage backend, since R2 is S3-compatible. Create subclasses for StaticStorage, PublicMediaStorage, and PrivateMediaStorage, setting bucket_name, custom_domain, and location from Django settings. Configure AWS_S3_ENDPOINT_URL to your R2 endpoint, AWS_S3_REGION_NAME to 'auto', and register each class under the STORAGES dict in settings.py. Install django-storages and boto3 via pip. Django developers migrating file storage to R2 track patterns like this on daily.dev.
How do I serve private files from Cloudflare R2 with signed URLs in Django?
Create a PrivateMediaStorage class inheriting from S3Boto3Storage with signature_version set to 's3v4' and querystring_auth set to True. Point it at a private R2 bucket (no public URL enabled). Files uploaded via this storage are served with time-limited signed URLs containing X-Amz-Algorithm, X-Amz-Credential, X-Amz-Expires, and X-Amz-Signature query parameters. Requests without a valid signature return 403. Teams handling private user uploads in Django find R2 signed-URL setups covered on daily.dev.
What are the limitations of Cloudflare R2 compared to AWS S3?
Cloudflare R2 lacks object versioning, supports only bucket-level access controls (no per-object ACLs), and offers weak analytics with no intelligent storage tiering. On the upside, R2 has zero egress fees and a free tier covering 10 GB storage, 1 million write operations, and 10 million read operations per month. Engineers choosing between R2 and S3 for a new project find trade-off discussions like this on daily.dev.