Django (s3) doesn't use custom domain for statics

I have S3 object storage with a CDN infront of it (on DigitalOcean). I have pointed my domain cdn.domain.com to the cdn & this is working fine.

In Django I am using django-storages[s3] to connect with S3 and store static files. This works and static files are being transferred to my bucket on running collectstatic.

Whenever I try to access any file the url doesn't get built properly. On localhost it looks like this http://127.0.0.1/http//cdn.domain.com.

I have a modified implementation of the S3Storage to automatically handle ACLs based on my configuraton.

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 that sets the urls

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",
        },
    },
}

I've been unable to get django to load statics from my cdn subdomain directly.

Вернуться на верх