Django (s3) не использует пользовательский домен для статики
У меня есть объектное хранилище S3 с CDN перед ним (на DigitalOcean). Я указал свой домен cdn.domain.com
на cdn & это работает нормально.
В Django я использую django-storages[s3]
для соединения с S3 и хранения статических файлов. Это работает, и статические файлы передаются в мой бакет при запуске collectstatic
.
Всякий раз, когда я пытаюсь получить доступ к любому файлу, url не создается должным образом. На localhost это выглядит следующим образом http://127.0.0.1/http//cdn.domain.com
.
У меня есть модифицированная реализация S3Storage
для автоматической обработки ACL на основе моей конфигурации.
import fnmatch
from django.conf import settings
from storages.backends.s3 import S3Storage
class StorageBackend(S3Storage):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.default_acl = getattr(settings, "AWS_DEFAULT_ACL", "private")
self.default_cache_control = getattr(
settings, "AWS_S3_OBJECT_PARAMETERS", {}
).get("CacheControl", "max-age=86400")
self.public_folders = getattr(settings, "S3_PUBLIC_FOLDERS", {})
def _save(self, name, content):
self.default_acl = self._get_acl(name)
self.object_parameters = {"CacheControl": self._get_cache_control(name)}
return super()._save(name, content)
def _get_acl(self, name):
for folder, config in self.public_folders.items():
if self._match_pattern(name, folder):
if "files" not in config or not config["files"]:
return "public-read"
for pattern in config["files"]:
if self._match_pattern(name, pattern):
return "public-read"
return "private"
def _get_cache_control(self, name):
for folder, config in self.public_folders.items():
if self._match_pattern(name, folder):
if "cache" in config:
if "files" not in config or not config["files"]:
return config["cache"]
for pattern in config["files"]:
if self._match_pattern(name, pattern):
return config["cache"]
return self.default_cache_control
def _match_pattern(self, path, pattern):
if pattern == "":
return "/" not in path
return fnmatch.fnmatch(path, pattern)
Settings.py, который устанавливает урлы
STATIC_URL = "https://cdn.domain.com/"
AWS_S3_CUSTOM_DOMAIN = "cdn.domain.com" # Repetitive with
STORAGES = {
"default": {
"BACKEND": "mypackage.s3.StorageBackend",
"OPTIONS": {
"bucket_name": "bucket",
"region_name": "region1",
"endpoint_url": "https://bucket.region.digitaloceanspaces.com",
"access_key": SPACES_ACCESS_KEY,
"secret_key": SPACES_SECRET_KEY,
"url_protocol": "https",
"custom_domain": "cdn.domain.com",
},
},
"staticfiles": {
"BACKEND": "mypackage.s3.StorageBackend",
"OPTIONS": {
"bucket_name": "bucket",
"region_name": "region1",
"endpoint_url": "https://bucket.region.digitaloceanspaces.com",
"access_key": SPACES_ACCESS_KEY,
"secret_key": SPACES_SECRET_KEY,
"url_protocol": "https",
"custom_domain": "cdn.domain.com",
},
},
}
Мне не удалось заставить django загружать статику с моего поддомена cdn напрямую.