Django静态资源无法访问
使用 django
2.2。
一般来说,使用指令 npm run build
得到打包的 dist
包,交给 nginx 做路由转换(配置 location /static
)即可,需要的只是在django配置可访问的 index.html
路径。
但是由于需要(?), 我想在本地进行测试,也就是说在没有 nginx, 开启 debug = True
的环境下调试。于是打开 python manage.py runserver
, 结果进入首页没有出现欢迎页面,打开 dev tools ,显示是这个样子的:
解决
解决方法:将 vue 工程文件夹在 INSTALLED_APPS
里面注册下就行。
INSTALLED_APPS = [
...
'blogfro',
...
]
但是在生产环境
DEBUG = False
下仍然会失效,因为这时需要我们打包到指定文件夹通过服务器反代了,这只能用作调试的时候使用。真正部署的时候还是配置服务器反代吧。
原理:
如果不注册 app, 那么即使写入文件夹, django 也不会扫描(根目录除外):
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR + '/blogfro/dist'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
STATICFILES_DIR = [
os.path.join(BASE_DIR, 'blogfro/dist/static'),
os.path.join(BASE_DIR, 'backend/static'),
os.path.join(BASE_DIR, 'static'),
]
如上所示我在 STATICFILES_DIR
中已经写入了 blogfro (也就是 vue 文件目录) 打包完成后的 static
文件夹,但是进入首页仍然白屏。
白屏表示模板 TEMPLATES
的路径正常,但是静态文件仍然加载不出来。这就需要注册 app 。注册后就能够扫描到静态文件。
注册后就成功显示了首页:
附注: 在踩坑的时候遇到的一些 ”发现“ :
在没有加载 app时,发现把 css 与 js 文件放在一个已经注册 app(backend)的静态文件夹中,能够正常显示。这验证了静态文件夹的扫描需要注册 app。
几个静态路径:
以我的项目为例:
STATIC_URL = '/static/'
STATICFILES_DIR = [
os.path.join(BASE_DIR, 'blogfro/dist/static'),
os.path.join(BASE_DIR, 'backend/static'),
os.path.join(BASE_DIR, 'static'),
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Debug 下
在 debug 模式下,只需要 STATIC_URL
与 STATICFILES_DIR
即可。
根据 django 文档 说法,STATIC_URL
是路径的映射。服务器会将匹配到它的路径视为静态文件请求,然后进入 STATICFILES_DIR
指定目录下查找,并总是尝试返回匹配到的第一个结果。
生产环境下
在生产模式下(关闭 debug ),对静态文件的引用会失效。换句话说,出于性能考虑,我们不使用django服务器进行静态资源请求。我们常使用其他反代服务器进行发送。
出于这个考虑,django 使用了 collectstatic
指令,能将所有 STATICFILES_DIR
下的文件打包到 STATIC_ROOT
下。之后只要配置反代服务器应用这个静态文件夹就行了。
最后
之后就能直接对 blogfro
进行开发了,开发完成后使用 npm run build
, 然后直接开启 django 服务器就能进行测试。最后打包上线的时候将dist下的内容复制到到 STATIC_ROOT
下,然后 python manage.py collectstatic
(主要是收集 admin )的资源。
总结
其实问题不是完全解决,但这是因为 vue + django
造成的。
django 使用自己的静态路径索引,必然有可能与vue发生冲突,为了处理必须进行调试。
使用 django 与 vue, 意味着希望进行前后端分离,所以开发过程本身就是隔离的。双方的交集应该是最后部署的时候(vue 打包, django 开启生产模式, 反代服务器开启(如 nginx))。这时候静态文件夹归反代服务器管理,不会出现这样的问题。
由于我只有一个人(太惨了),所以产生了同时调试 vue 与 django 的需求,这才导致了上面问题的产生。