aiohttp
免费Use when building Python async HTTP services or clients with aiohttp - web server routing, middleware, WebSocket, SSE, streaming, client sessions, pytest-aiohttp testing, or troubleshooting SSL and timeout issues
中文简介正在准备中。当前显示原文说明。
Use when configuring django-storages for cloud file storage - STORAGES setting, Amazon S3, Google Cloud Storage and Azure backends, signed URLs, CDN and caching, multipart uploads, or storage testing
中文简介正在准备中。当前显示原文说明。
查看安装方法安装前可以查看交给 AI 代理的指令内容。
Django package for cloud storage backends. Provides a unified API for storing files across different cloud providers.
pip install django-storages[boto3] # AWS S3 example
# settings.py
import os
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"bucket_name": "my-app-media",
"region_name": "us-east-1",
},
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
},
}
# Credentials from environment (never in settings)
AWS_ACCESS_KEY_ID = os.environ["AWS_ACCESS_KEY_ID"]
AWS_SECRET_ACCESS_KEY = os.environ["AWS_SECRET_ACCESS_KEY"]
The single most common failure with user-uploaded files is non-ASCII characters, spaces, and special characters in filenames.
报告.pdf, vacation été.jpg) may not survive URL encoding%20 or + inconsistently across backendsupload_toimport os
import unicodedata
import uuid
from django.utils.text import slugify
def sanitize_upload_path(instance, filename):
"""
Sanitize filename and guarantee uniqueness.
Never trust client-supplied filenames.
"""
# Extract extension
ext = os.path.splitext(filename)[1]
# Normalize unicode (NFKD decomposes, then slugify strips diacritics)
sanitized = unicodedata.normalize("NFKD", filename)
sanitized = slugify(sanitized)
# Fallback if slugify produces empty string
if not sanitized:
sanitized = "file"
# Append random suffix to guarantee uniqueness
unique_id = uuid.uuid4().hex[:8]
new_filename = f"{sanitized}_{unique_id}{ext}"
return f"uploads/{new_filename}"
class Document(models.Model):
title = models.CharField(max_length=255)
file = models.FileField(upload_to=sanitize_upload_path)
slugify?report.pdf → second overwrites firstslugify produces empty stringclass Document(models.Model):
title = models.CharField(max_length=255)
original_name = models.CharField(max_length=255) # For download
file = models.FileField(upload_to=sanitize_upload_path)
The STORAGES dict replaces DEFAULT_FILE_STORAGE and STATICFILES_STORAGE (removed in Django 6.0).
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"bucket_name": "my-app-media",
"region_name": "us-east-1",
},
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
},
}
Problem: Hardcoding the backend in code forces environment-specific branching.
# ❌ DON'T: Environment branching in code
if settings.DEBUG:
from django.core.files.storage import FileSystemStorage
storage = FileSystemStorage()
else:
from storages.backends.s3 import S3Storage
storage = S3Storage()
Solution: Swap backends via settings per environment.
# settings/dev.py
STORAGES = {
"default": {"BACKEND": "django.core.files.storage.FileSystemStorage"},
}
# settings/prod.py
STORAGES = {
"default": {"BACKEND": "storages.backends.s3.S3Storage"},
}
# Code stays the same:
from django.core.files.storage import default_storage
default_storage.save("file.txt", content)
Problem: A leaked settings file = leaked cloud credentials.
# ❌ DON'T: Hardcoded credentials
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"access_key": "AKIAIOSFODNN7EXAMPLE", # Leaked = compromised
"secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
},
}
Solution: Environment variables or IAM roles.
# ✅ DO: Environment variables
import os
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"access_key": os.environ["AWS_ACCESS_KEY_ID"],
"secret_key": os.environ["AWS_SECRET_ACCESS_KEY"],
},
},
}
# ✅ BETTER: IAM role (EC2/ECS) - no credentials needed
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"bucket_name": "my-app-media",
# No access_key/secret_key → uses IAM role
},
},
}
default_acl: When to Make Files PublicSTORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"default_acl": "public-read", # or None for private
},
},
}
Set public-read only for genuinely public assets:
Keep None (private) for:
Why it matters: Public buckets are a common security incident vector. Obscurity is not security.
querystring_auth: Signed URLsSTORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"querystring_auth": True, # Require signatures (private)
"querystring_expire": 3600, # 1 hour expiry
},
},
}
When querystring_auth = False:
Critical: If querystring_auth = False, signed URLs must carry their own expiry via url() parameters:
# Private bucket with querystring_auth=False (e.g., CDN-protected)
# You MUST pass expiry explicitly:
url = storage.url("file.pdf", expire=3600) # Expires in 1 hour
When you need signed URLs:
# Download as attachment (forces download with original filename)
url = storage.url(
"documents/report.pdf",
parameters={"ResponseContentDisposition": "attachment; filename=report.pdf"}
)
# Temporary access (e.g., password-protected page)
url = storage.url("private/secret.pdf", expire=1800) # 30 minutes
Architecture:
querystring_auth = True)# settings.py
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"bucket_name": "my-app-private",
"region_name": "us-east-1",
"querystring_auth": True, # Private bucket
"custom_domain": "d1234abcdef.cloudfront.net", # CDN domain
},
},
}
Differentiate cacheable public assets from private content:
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"object_parameters": {
# Public static assets: cache aggressively
"CacheControl": "public, max-age=31536000, immutable",
},
},
},
}
# Per-file cache control (overrides default)
from django.core.files.storage import default_storage
# Public image - cache for a year
default_storage.save("images/logo.png", content)
# S3 object params can be set via custom storage subclass or boto3 directly
# Temporary report - don't cache
default_storage.save("reports/daily.pdf", content)
CloudFront:
import boto3
def invalidate_cloudfront(paths):
"""
Invalidate CloudFront cache for given paths.
Cost: $0.005 per path, 1000 paths/month free.
"""
cloudfront = boto3.client("cloudfront")
distribution_id = "E1234ABCDEF"
cloudfront.create_invalidation(
DistributionId=distribution_id,
InvalidationBatch={
"Id": f"invalidation-{uuid.uuid4().hex[:8]}",
"Paths": {
"Quantity": len(paths),
"Items": paths,
},
},
)
# Invalidate specific files
invalidate_cloudfront(["/images/logo.png", "/reports/daily.pdf"])
# Invalidate by prefix (expensive - use sparingly)
invalidate_cloudfront(["/reports/*"]) # Wildcards supported in CloudFront
Azure CDN:
# Azure CDN Classic invalidation
from azure.cdn.management import CdnManagementClient
client = CdnManagementClient(credential, subscription_id)
client.profiles.begin_create_or_update(...)
# Invalidate by path prefix
client.endpoints.invalidate(
resource_group_name="my-rg",
profile_name="my-profile",
endpoint_name="my-endpoint",
content_paths=["/images/*", "/css/*"],
)
Source: AWS CloudFront Invalidations | Azure CDN Invalidation
Use Django's FileSystemStorage instead:
# settings/dev.py
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
"OPTIONS": {
"location": "/tmp/media", # or MEDIA_ROOT
},
},
}
Why: No network calls, no credentials, instant file access for debugging.
Use a build pipeline instead of storage backend for assets that ship with code:
Why: These are versioned at deploy time, not user-uploaded. Use collectstatic with ManifestStaticFilesStorage.
STORAGES = {
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
},
}
Use the SDK directly:
import boto3
s3 = boto3.client("s3")
s3.upload_file("local.txt", "my-bucket", "remote.txt")
Why: If you only use one bucket and never swap backends, django-storages adds indirection without benefit.
Bypass Django entirely:
# View that returns upload credentials
def get_upload_url(request):
s3 = boto3.client("s3")
url = s3.generate_presigned_url(
"put_object",
Params={
"Bucket": "my-bucket",
"Key": f"uploads/{uuid.uuid4()}.pdf",
"ContentType": "application/pdf",
},
ExpiresIn=3600,
)
return JsonResponse({"url": url, "key": key})
# Browser uploads directly to S3
# POST { url, key } → client PUTs file to S3
Why: Large file uploads shouldn't proxy through Django. Use presigned URLs for direct browser-to-storage uploads.
Most settings have sensible defaults. Use these only when you need specific behavior:
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
# Only set if you need non-default storage class
"object_parameters": {
"StorageClass": "STANDARD_IA", # Infrequent access (cheaper)
},
# Only set if you want to prevent overwrites
"file_overwrite": False, # Default: True (overwrites same name)
# Only set if using KMS encryption
"object_parameters": {
"SSEKMSKeyId": "arn:aws:kms:...",
},
# Only set if bucket is in different region
"region_name": "eu-west-1", # Default: us-east-1
# Only set if using custom domain/CDN
"custom_domain": "cdn.example.com",
# Only set if you need non-default ACL
"default_acl": "public-read", # Default: None (private)
# Only set if you need URL prefix in bucket
"location": "media/", # All files stored under media/
},
},
}
Source: django-storages S3 Backend Docs
# settings.py
from pathlib import Path
env = os.environ.get("DJANGO_ENV", "development")
if env == "development":
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
}
else:
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {
"bucket_name": os.environ["AWS_STORAGE_BUCKET_NAME"],
},
},
}
from unittest.mock import patch
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
class DocumentUploadTest(TestCase):
@patch("django.core.files.storage.default_storage")
def test_upload(self, mock_storage):
mock_storage.save.return_value = "uploads/file.txt"
file = SimpleUploadedFile("file.txt", b"content")
path = default_storage.save("file.txt", file)
self.assertEqual(path, "uploads/file.txt")
mock_storage.save.assert_called_once()
Load these reference files for detailed backend-specific guidance:
references/providers.md — Amazon S3, Google Cloud Storage, Azure Blob Storage detailed setupreferences/models-code-urls.md — FileField usage, direct backend access, uploads, signed URLsreferences/cloud-features.md — Encryption, CDN, caching, multipart uploads (load when implementing provider-specific features)还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
Use when building Python async HTTP services or clients with aiohttp - web server routing, middleware, WebSocket, SSE, streaming, client sessions, pytest-aiohttp testing, or troubleshooting SSL and timeout issues
中文简介正在准备中。当前显示原文说明。
Use when doing structural code search and rewriting - ast-grep linting, refactoring, multi-language patterns
中文简介正在准备中。当前显示原文说明。
Use when building GBA games with the BPCore Lua engine - entity, sprite and tilemap functions, SRAM save and load, link cable multiplayer protocol, camera and scrolling, or optimization patterns
中文简介正在准备中。当前显示原文说明。
Use when running background tasks with Celery - worker and broker configuration (Redis, RabbitMQ), task routing by name vs queue, chains/groups/chords, retry patterns (autoretry_for, retry_backoff), acks_late semantics, failure detection, and monitoring with Flower
中文简介正在准备中。当前显示原文说明。
Use when building Django applications - security hardening, authentication and permissions, ORM optimization, PostgreSQL features, Django 6.0, migrations, testing, and ecosystem libraries
中文简介正在准备中。当前显示原文说明。
Use when customizing Django Admin - save_formset, get_search_results, formsets, queryset optimization, db_index, custom URLs
中文简介正在准备中。当前显示原文说明。