Как исправить ошибку django-filer 404 на DigitalOcean?

У меня есть приложение django-cms, работающее на DigitalOcean. Создание папок и загрузка файлов с помощью filer работает отлично.

При загрузке загруженных файлов я получаю ошибку 404 - например, на этом url:

https://my_app.ondigitalocean.app/en/media/filer_public/39/d9/39d9ff20-1aa8-48e5-9b8f-113fc71e534b/atest.pdf/

Файл присутствует в файловой системе: Screenshot of file on filesystem

settings.py

MEDIA_URL = "media/"
MEDIA_ROOT = str(BASE_DIR / "media")

На локальном сервере разработки все работает нормально при DEBUG=True, но также не работает при DEBUG=False.

Когда DEBUG=True, Django напрямую управляет статическими и медиа файлами. При использовании DEBUG=False это поведение меняется по соображениям производительности и безопасности. Обычно в производстве статические и медиа файлы управляются веб-сервером, например Nginx. У вас должна быть конфигурация, подобная этой:

server {
    listen 80;
    server_name my_app.ondigitalocean.app;

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/my_app.sock;
    }

    location /media/ {
        alias /path/to/your/project/media/;  # this must be what you have in MEDIA_ROOT
    }

    location /static/ {
        alias /path/to/your/project/static/;
    }
}

Ответ 1

После некоторого поиска я нашел этот вопрос: Почему настройка DEBUG=False делает мой django Static Files Access неудачным?

После изменения urls.py файлы стали обслуживаться идеально.

...
from django.urls import re_path
from django.views.static import serve

urlpatterns += (
    re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
)

Но!

Моя папка media находилась в папке проекта (где живет manage.py) и удалялась каждый раз при новом развертывании приложения, поэтому:

Ответ 2

Я выбрал использование django-storages.

https://django-storages.readthedocs.io/en/latest/

Создайте объектное хранилище Spaces на DigitalOcean (или любое другое облачное хранилище) и измените settings.py:

INSTALLED_APPS = [
    ...
    'storages', # add storages after installing it with pip
    ...
]

...

AWS_S3_ACCESS_KEY_ID = os.getenv("AWS_S3_ACCESS_KEY_ID", "False")
AWS_S3_SECRET_ACCESS_KEY = os.getenv("AWS_S3_SECRET_ACCESS_KEY", "False")
AWS_STORAGE_BUCKET_NAME = "your_bucket_name"
AWS_S3_OBJECT_PARAMETERS = {"CacheControl": "max-age=86400"}
AWS_S3_REGION_NAME = "fra1" # might be different for you
AWS_S3_ENDPOINT_URL = "https://fra1.digitaloceanspaces.com" # might be different for you
AWS_LOCATION = "a_folder_name"
DEFAULT_FILE_STORAGE = "storages.backends.s3.S3Storage"

Заметка

Хотя я использую Django >= 5, рекомендуемый стиль (см. ниже) не работал для меня, поэтому я придерживался старого стиля.

STORAGES = {
    "default": {
        "BACKEND": "storages.backends.s3.S3Storage",
        "OPTIONS": {
          ...your_options_here
        },
    },
}
Вернуться на верх