12月10, 2017

Django关闭DEBUG后静态资源加载失败的解决办法

Django框架仅在开发模式下提供静态文件服务,开启DEBUG模式(DEBUG=True)时,Django内置的服务器是提供静态文件的服务的,所以Css、Js等文件访问都没有问题,但是关闭DEBUG模式(DEBUG=True)后,Django便不提供静态文件服务了,静态资源加载就会出现问题,最直观的表现形式就是网页没有样式了,本文主要记录一下解决方法

一、改变运行方式

使用--insecure参数强制django处理静态文件:

python manage.py runserver 0:8080 --insecure

简单、暴力,看过很多介绍关于处理静态资源的方法,都推荐这种方案,但是我不推荐,这里引用一下官方说明:

Use the --insecure option to force serving of static files with the staticfiles app even if the DEBUG setting is False. By using this you acknowledge the fact that it’s grossly inefficient and probably insecure. This is only intended for local development, should never be used in production and is only available if the staticfiles app is in your project’s INSTALLED_APPS setting. runserver --insecure doesn’t work with CachedStaticFilesStorage.

翻译过来就是:

虽然可以使用"--insecure"参数在"DEBUG"设置为False的情况下 强制使用"staticfiles"对静态文件进行服务,但是效率极低而且可能不安全。这种方法仅适用于本地开发, 不应在生产环境中使用, 而且只有在"staticfiles""INSTALLED_APPS"中设置了才可使用。另外就是"--insecure"参数对"CachedStaticFilesStorage"不起作用

所以我不推荐使用这种方法

二、使用"STATIC"设置(推荐)

I、确定项目中引用了staticfiles程序:

确保setting.py文件中INSTALLED_APPS项中引用了django.contrib.staticfiles,示例如下:

INSTALLED_APPS = [
    'django.contrib.staticfiles',
]

II、设置STATIC_ROOT

目录的绝对路径,collectstatic将收集所有App中/static/文件夹中的静态资源保存至STATIC_ROOT

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

一定要使用绝对路径,上面的路径表示的是该项目根目录下的/static/文件夹

III、收集静态资源:

执行命令:

python manage.py collectstatic

如果项目根目录下不存在/static/文件夹会直接创建并复制文件,如果已经存在/static/文件夹,则会提示是否覆盖原有文件,输入yes,执行操作

IV、设置STATIC_URL

静态资源的URL路径,使用'/static/'值即可

STATIC_URL = '/static/'

V、使用Nginx代理:

这里使用Nginx做Web服务器,在server段中加入静态资源路径代理,内容如下:

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

说明:

①、location后面的/static/的值,即为第IV步中设置的'STATIC_URL'的值

②、alias的值即为第III步中项目根目录的绝对路径,示例,如项目名字为myproject,项目文件放在/data/www目录下,则alias的值为/data/www/myproject/static/

完整的Nginx配置文件如下:

server {
  listen 80;
  server_name xxx.com;
  location / {
    client_max_body_size 0;
    gzip off;
    proxy_http_version 1.1;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://127.0.0.1:8090$request_uri;
    proxy_redirect off;
  }
  location /static/ {
    alias /data/www/myproject/static/;
  }
}

这样就可以实现静态资源的集中管理了

VI、关于后续:

如果修改了静态文件,想要在产品上展现效果,则需要进行如下操作:

①、进入项目目录

②、执行如下命令:

python manage.py collectstatic

③、输入yes确认覆盖内容

以上三步执行完毕,更新的的静态资源则会重新收集在STATIC_ROOT目录中,刷新页面即可看到修改的效果

上面就是总结的两种关于Django关闭DEBUG后静态资源加载失败的解决办法,推荐使用第二种方法,虽然步骤繁琐了点,但是是一种比较行之有效的长久的解决方案。

本文链接:https://www.shaobin.wang/post/17.html

Comments