当 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)。
我将 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)。