Django игнорирует статическую конфигурацию при загрузке в S3

Раньше у меня была такая же проблема с медиафайлами, я сделал все настройки, но django продолжал сохранять медиафайлы локально, а не в S3, я думаю, что это было решено путем реализации пользовательского класса, наследующего от S3Boto3Storage. Теперь я хочу сохранить свои статические файлы в том же S3, но у меня та же проблема, django полностью игнорирует мою конфигурацию и продолжает сохранять файлы локально в директории staticfiles.

Вот мои установленные приложения

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'storages',
    'app',
    'crispy_forms',
    'crispy_bootstrap5',
]

Настройка медиафайла в настоящее время работает:

AWS_ACCESS_KEY_ID = config('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = config('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = config('AWS_STORAGE_BUCKET_NAME')
AWS_S3_ENDPOINT_URL = config('AWS_S3_ENDPOINT_URL')
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}
AWS_MEDIA_LOCATION = 'media'
AWS_S3_REGION_NAME = config('AWS_S3_REGION_NAME')
AWS_DEFAULT_ACL = 'public-read'
AWS_QUERYSTRING_AUTH = False
AWS_S3_CONNECTION_TIMEOUT = 60
MEDIA_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.{AWS_S3_REGION_NAME}.digitaloceanspaces.com/{AWS_MEDIA_LOCATION}/"
PUBLIC_MEDIA_LOCATION = 'media'
DEFAULT_FILE_STORAGE = 'cms.storage_backends.PublicMediaStorage'
DEFAULT_PROFILE_PHOTO=config('DEFAULT_PROFILE_PHOTO')

Статическая конфигурация файла, идея состоит в том, чтобы читать CMS_STATIC_LOCAL_STORAGE из переменных окружения, но для целей тестирования значение устанавливается постоянно:

CMS_STATIC_LOCAL_STORAGE = False
print('Static Local Storage: ', CMS_STATIC_LOCAL_STORAGE)
AWS_STATIC_LOCATION = 'static'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
if CMS_STATIC_LOCAL_STORAGE:
    STATIC_URL = '/static/'
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'static'),
    ]
else:
    STATIC_URL = f"https://{AWS_S3_REGION_NAME}.digitaloceanspaces.com/{AWS_STORAGE_BUCKET_NAME}/{AWS_STATIC_LOCATION}/"
    STATICFILES_STORAGE = 'cms.storage_backends.StaticStorage'

Обратите внимание, что я также уже пробовал настроить его следующим образом STATIC_URL = f"https://{AWS_STORAGE_BUCKET_NAME}.{AWS_S3_REGION_NAME}.digitaloceanspaces.com/{AWS_STATIC_LOCATION}/"

Файл storage_backends.py:

from storages.backends.s3boto3 import S3Boto3Storage

class PublicMediaStorage(S3Boto3Storage):
    location = 'media'
    default_acl = 'public-read'
    file_overwrite = False

    @property
    def querystring_auth(self):
        return False

class StaticStorage(S3Boto3Storage):
    location = 'static'
    default_acl = 'public-read'

Клянусь, эта проблема сводит меня с ума, я пытаюсь решить ее уже несколько часов. Как я уже говорил, то же самое произошло с медиафайлами, и я думаю, что решил эту проблему с помощью пользовательского класса, но в случае со статическими файлами я нигде не могу найти решение.

(env)  msi@fedora  ~/Escritorio/django_cms   develop ±  ./manage.py collectstatic --no-input
Running server with DEBUG=False and ALLOWED_HOSTS=['localhost']
Static Local Storage:  False

Сначала я попытался сделать настройки динамически в соответствии с переменной CMS_STATIC_LOCAL_STORAGE, но даже попробовал сделать это напрямую и получил тот же результат. Я также попытался поместить объявление STATIC_ROOT внутрь if true переменной CMS_STATIC_LOCAL_STORAGE, но получил в консоли ошибку следующего вида:

(env)  msi@fedora  ~/Escritorio/django_cms   develop ±  ./manage.py collectstatic --no-input
Running server with DEBUG=False and ALLOWED_HOSTS=['localhost']
Static Local Storage:  False
Traceback (most recent call last):
  File "/home/msi/Escritorio/django_cms/./manage.py", line 22, in <module>
    main()
...
...
  File "/home/msi/Escritorio/django_cms/env/lib/python3.11/site-packages/django/contrib/staticfiles/storage.py", line 39, in path
    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.

UPDATE. При тестировании я понял, что фронтенд уже перенаправляет на S3 Digital Ocean, но при выполнении collectstatic он продолжает сохраняться в моем локальном, поэтому фронтенд отображается некорректно.

DOM

Скорее всего, у меня та же проблема. Вы недавно обновились до версии Django 5.1?

S3 настроен как всегда, но default_storage.url() теперь возвращает локальные URL в Django 5.1.

$ python manage.py shell
Python 3.10.0
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.conf import settings
>>> settings.DEFAULT_FILE_STORAGE
'storages.backends.s3boto3.S3Boto3Storage'
>>> from django.core.files.storage import default_storage
>>> default_storage.url('subfolder/dummyfile.txt')
>>> 'subfolder/dummyfile.txt' (instead of https://{}.s3.amazonaws.com/subfolder/dummyfile.txt?signature...)

Похоже, что поддержка Django 5.1 была добавлена несколько дней назад в master-ветку, но еще не в pip.

Вы можете:

  • a) перейдите с версии Django 5.1 на 5.0 (у меня снова работает)
  • b) попробуйте добавить последний коммит https://github.com/jschneier/django-storages/commit/0fc0650a3a2ba5ac088b127d7771634a26f2793c в ваш requirements.txt, чтобы загрузить последнюю версию (у меня не работает)
Вернуться на верх