Статические файлы Django не загружаются должным образом в Digitalocean Spaces с помощью S3

Я работаю над проектом django v5.1 и, как всегда, использую пространства digitalocean для своих статических и медиафайлов.

Вот конфигурация по умолчанию, которую я всегда использую:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Our apps
    ...,
    ...,
    ...,
    ...,
    # Third party apps
    'storages',
    
]

# DigitalOcean Spaces Configuration
AWS_ACCESS_KEY_ID = os.getenv('DO_SPACE_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.getenv('DO_SPACE_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.getenv('DO_SPACE_BUCKET_NAME')
AWS_S3_ENDPOINT_URL = f"https://{os.getenv('DO_SPACE_BUCKET_NAME')}.{os.getenv('DO_SPACE_REGION')}.digitaloceanspaces.com"
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',  # Cache static files for 1 day
}

# Static and Media Files Settings
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

# Static and Media URL
STATIC_URL = f"{AWS_S3_ENDPOINT_URL}/static/"
MEDIA_URL = f"{AWS_S3_ENDPOINT_URL}/media/"
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

# Optional configurations to prevent overwrite of files with the same name
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None

Но на этот раз я столкнулся с проблемами.

Обычно я не определяю STATIC_ROOT, так как использую Boto3, но теперь он выдает ошибку, если я не определяю его при запуске collectstatic:

django.core.exceptions.ImproperlyConfigured: 
You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.

Но когда я включаю его, он собирает статические файлы в папке staticfiles, которую я определил, вместо того, чтобы загружать их в пространство digitalocean.

Я не знаю, есть ли изменения в Django 5, но я попробовал протестировать загрузку S3, зайдя в оболочку django:

from storages.backends.s3boto3 import S3Boto3Storage
from django.core.files.base import ContentFile
storage.save('testfile.txt', ContentFile('This is a test file for DigitalOcean Spaces'))

И файл успешно загружен в мой spaces bucket.

enter image description here

В чем, по-видимому, заключается проблема? Есть ли кто-нибудь, кто сталкивался с этим в последней версии Django?

PS: Я использую Digitalocean для базы данных и пространства, и railway.app для развертывания приложения.

После долгих поисков я наконец нашел проблему. Это действительно было связано с версией Django.

Если вы используете Django <= 4.2: Вы будете использовать эти 2 строки:

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'

Если вы используете Django > 4.2: Вы будете использовать эти строки:

STORAGES = {
    "default": {
        "BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
    },
    "staticfiles" : {
        "BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
    },
}

Также вам нужно избавиться от определений STATIC_ROOT и MEDIA_ROOT.

Отличный материал, заставил меня исправить свой CDN.

Для моей CDN DigitalOcean spaces, использующей Django == 5.1.1, я смог добавить в settings.py

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static/') # It will be deactivated when running collectstatic. Active on localhost
]

STATIC_ROOT = BASE_DIR / 'staticfiles-cdn/' # It will be activated when running collectstatic. Active on server

from .cdn.conf import *

В /cdn/conf.py

STORAGES = {
    "default": {
        "BACKEND": f{AWS_STORAGE_BUCKET_NAME}.cdn.backends.MediaRootS3BotoStorage",
    },
    "staticfiles" : {
        "BACKEND": f"{AWS_STORAGE_BUCKET_NAME}.cdn.backends.StaticRootS3BotoStorage",
    },
}
Вернуться на верх