当 DEBUG 为 False 时 Django 停止提供静态文件

Django stops serving static files when DEBUG is False

我将 Docker Compose 与此 Docker 文件一起使用,将静态文件夹复制到 /static:

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install --upgrade pip && pip install -r requirements.txt
COPY static /static/
COPY . /code/

在我的设置文件中我使用:

if env == "dev":
    DEBUG = True
else:
    DEBUG = False
    SECURE_CONTENT_TYPE_NOSNIFF = True
    SECURE_BROWSER_XSS_FILTER = True
    X_FRAME_OPTIONS = "DENY"

STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]

STATICFILES_DIRS = [
    # os.path.join(BASE_DIR, "static/"),
    '/static'
]

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

静态文件在 dev 中工作,但是当我将 env 更改为 prod 时,我开始收到 404 错误。

所以你看到问题了吗?

虽然**强烈反对*在生产环境中使用 Django 中的静态文件(出于 非常 的充分理由),但我经常需要这样做。

在某些情况下,它是完全可以接受的(低流量、REST API 仅服务器等)。如果您需要这样做,这个片段应该会有所帮助。如果那是你的 django 风格,请调整 re_path 或使用 url()

from django.contrib.staticfiles.views import serve as serve_static

def _static_butler(request, path, **kwargs):
    """
    Serve static files using the django static files configuration
    WITHOUT collectstatic. This is slower, but very useful for API 
    only servers where the static files are really just for /admin

    Passing insecure=True allows serve_static to process, and ignores
    the DEBUG=False setting
    """
    return serve_static(request, path, insecure=True, **kwargs)

urlpatterns = [
    ...,
    re_path(r'static/(.+)', _static_butler)
]

注意:这个答案也是正确的,但我也接受了上面的答案(因为我的应用程序将收到非常低的流量。)

感谢您的评论。它们很有用。

这是我的新 docker 撰写文件:

version: '3.5'

services:
  nginx:
    image: nginx:latest
    ports:
      - "8002:8000"
    volumes:
      - $PWD:/code
      - ./config/nginx:/etc/nginx/conf.d
      - ./static:/static
    depends_on:
      - web
    networks:
      - my_net
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    env_file: .env
    volumes:
      - $PWD:/code
      - ./static:/static
    expose:
      - "8000"
    networks:
      - my_net

networks:
  my_net:
    driver: bridge

这是 Nginx 配置文件:

upstream web {
  ip_hash;
  server web:8000;
}

server {

    location /static/ {
        autoindex on;
        alias /static/;
    }

    location / {
        proxy_pass http://web/;
    }
    listen 8000;
    server_name localhost;
}

您还应该将 "web" 添加到允许的主机:

ALLOWED_HOSTS = ['0.0.0.0', 'localhost', 'web']

更新: settings.py 文件:

STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
    # '/static'
]

STATIC_ROOT = '/static' #os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

正如@dirkgroten 所说,您可以在您服务的静态文件中设置到期时间header。

另一种解决方案是使用 Whitenoise(感谢 Daniel Roseman)。