Django Static url 无法与 Digital Ocean CDN 一起使用 {% static %}
Django Static url not working with {% static %} with Digital Ocean CDN
我的静态文件存储在 DigitalOcean CDN 中。我有多个 spaces,1 个用于客户端,1 个用于静态资产,我使用 django-storages。
这是我的配置:
AWS_S3_REGION_NAME = 'nyc3'
AWS_S3_ENDPOINT_URL = f'https://{AWS_S3_REGION_NAME}.digitaloceanspaces.com'
AWS_DEFAULT_ACL = 'private'
AWS_DEFAULT_BUCKET = 'exactestate-staging'
AWS_RESOURCE = session.resource('s3',
region_name=AWS_S3_REGION_NAME,
endpoint_url=AWS_S3_ENDPOINT_URL,
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
AWS_CLIENT = boto3.client('s3',
region_name=AWS_S3_REGION_NAME,
endpoint_url=AWS_S3_ENDPOINT_URL,
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
# Django’s STATIC_URL must end in a slash and the AWS_S3_CUSTOM_DOMAIN must not. It is best to set this variable independently of STATIC_URL.
AWS_S3_CUSTOM_DOMAIN = f'{AWS_DEFAULT_BUCKET}.{AWS_S3_REGION_NAME}.digitaloceanspaces.com'
STATIC_URL = f'https://{AWS_DEFAULT_BUCKET}.{AWS_S3_REGION_NAME}.digitaloceanspaces.com/static/'
STATICFILES_STORAGE = 'storage_backends.StaticStorage'
出于某种原因,如果我没有:AWS_S3_CUSTOM_DOMAIN = f'{AWS_DEFAULT_BUCKET}.{AWS_S3_REGION_NAME}.digitaloceanspaces.com'
设置,我的 {% static %}
标签使用 AWS_S3_ENDPOINT_URL
作为值...但我需要它来使用我设置的内容AWS_S3_CUSTOM_DOMAIN
.
通常设置 AWS_S3_CUSTOM_DOMAIN
会很好,但现在所有 file.url
调用也转到静态而不是我的客户端 space...我该如何解决这个问题?
好吧,我想通了一点并通过改变我的 StaticStorage class 来构建我需要的适当 URLs 解决了我的问题。
from abc import ABC
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class StaticStorage(S3Boto3Storage, ABC):
def __init__(self, *args, **kwargs):
super().__init__( *args, **kwargs)
if hasattr(settings, 'STAGING') and settings.STAGING is True:
# will have different static area
self.bucket_name = 'exactestate-stg'
self.region_name = 'sfo2'
self.endpoint = f'https://{self.region_name}.digitaloceanspaces.com'
# for building static is already in name
# no cdn for staging
self.static_url = f'https://{self.bucket_name}.{self.region_name}.digitaloceanspaces.com/'
else:
self.bucket_name = 'exactestate-prod'
self.region_name = 'sfo2'
self.endpoint = f'https://{self.region_name}.digitaloceanspaces.com'
self.static_url = f'https://{self.bucket_name}.{self.region_name}.cdn.digitaloceanspaces.com/'
location = 'static'
default_acl = 'public-read'
# fix to fix the url for staging and prod to have the right url for {% static ... %]
def url(self, name, parameters=None, expire=None, http_method=None):
# Preserve the trailing slash after normalizing the path.
name = self._normalize_name(self._clean_name(name))
params = parameters.copy() if parameters else {}
params['Bucket'] = self.bucket.name
params['Key'] = name
url = self.bucket.meta.client.generate_presigned_url('get_object', Params=params,
ExpiresIn=expire, HttpMethod=http_method)
# if self.querystring_auth:
# return url
val_to_return = self._strip_signing_parameters(url)
new_val = f'{self.static_url}{name}' # this works
return new_val
基本上我的问题是更改 AWS_S3_CUSTOM_DOMAIN
改变了用于我的文件的域,我无法再构建正确的 URL,因为它覆盖了端点 url。为了解决这个问题,我简单地采用了 S3Boto3Storage
中的 url()
方法,并确保我的 URL 对于我的 CDN 是准确的。
我的静态文件存储在 DigitalOcean CDN 中。我有多个 spaces,1 个用于客户端,1 个用于静态资产,我使用 django-storages。
这是我的配置:
AWS_S3_REGION_NAME = 'nyc3'
AWS_S3_ENDPOINT_URL = f'https://{AWS_S3_REGION_NAME}.digitaloceanspaces.com'
AWS_DEFAULT_ACL = 'private'
AWS_DEFAULT_BUCKET = 'exactestate-staging'
AWS_RESOURCE = session.resource('s3',
region_name=AWS_S3_REGION_NAME,
endpoint_url=AWS_S3_ENDPOINT_URL,
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
AWS_CLIENT = boto3.client('s3',
region_name=AWS_S3_REGION_NAME,
endpoint_url=AWS_S3_ENDPOINT_URL,
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
# Django’s STATIC_URL must end in a slash and the AWS_S3_CUSTOM_DOMAIN must not. It is best to set this variable independently of STATIC_URL.
AWS_S3_CUSTOM_DOMAIN = f'{AWS_DEFAULT_BUCKET}.{AWS_S3_REGION_NAME}.digitaloceanspaces.com'
STATIC_URL = f'https://{AWS_DEFAULT_BUCKET}.{AWS_S3_REGION_NAME}.digitaloceanspaces.com/static/'
STATICFILES_STORAGE = 'storage_backends.StaticStorage'
出于某种原因,如果我没有:AWS_S3_CUSTOM_DOMAIN = f'{AWS_DEFAULT_BUCKET}.{AWS_S3_REGION_NAME}.digitaloceanspaces.com'
设置,我的 {% static %}
标签使用 AWS_S3_ENDPOINT_URL
作为值...但我需要它来使用我设置的内容AWS_S3_CUSTOM_DOMAIN
.
通常设置 AWS_S3_CUSTOM_DOMAIN
会很好,但现在所有 file.url
调用也转到静态而不是我的客户端 space...我该如何解决这个问题?
好吧,我想通了一点并通过改变我的 StaticStorage class 来构建我需要的适当 URLs 解决了我的问题。
from abc import ABC
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class StaticStorage(S3Boto3Storage, ABC):
def __init__(self, *args, **kwargs):
super().__init__( *args, **kwargs)
if hasattr(settings, 'STAGING') and settings.STAGING is True:
# will have different static area
self.bucket_name = 'exactestate-stg'
self.region_name = 'sfo2'
self.endpoint = f'https://{self.region_name}.digitaloceanspaces.com'
# for building static is already in name
# no cdn for staging
self.static_url = f'https://{self.bucket_name}.{self.region_name}.digitaloceanspaces.com/'
else:
self.bucket_name = 'exactestate-prod'
self.region_name = 'sfo2'
self.endpoint = f'https://{self.region_name}.digitaloceanspaces.com'
self.static_url = f'https://{self.bucket_name}.{self.region_name}.cdn.digitaloceanspaces.com/'
location = 'static'
default_acl = 'public-read'
# fix to fix the url for staging and prod to have the right url for {% static ... %]
def url(self, name, parameters=None, expire=None, http_method=None):
# Preserve the trailing slash after normalizing the path.
name = self._normalize_name(self._clean_name(name))
params = parameters.copy() if parameters else {}
params['Bucket'] = self.bucket.name
params['Key'] = name
url = self.bucket.meta.client.generate_presigned_url('get_object', Params=params,
ExpiresIn=expire, HttpMethod=http_method)
# if self.querystring_auth:
# return url
val_to_return = self._strip_signing_parameters(url)
new_val = f'{self.static_url}{name}' # this works
return new_val
基本上我的问题是更改 AWS_S3_CUSTOM_DOMAIN
改变了用于我的文件的域,我无法再构建正确的 URL,因为它覆盖了端点 url。为了解决这个问题,我简单地采用了 S3Boto3Storage
中的 url()
方法,并确保我的 URL 对于我的 CDN 是准确的。