p起步
線上部署時因設置了 settings.DEBUG = False 會導致靜態文件都是 404 的情況。主要原因是應為關閉DEBUG模式后,Django 便不提供靜態文件服務了。
runserver 的啟動
如果運行是通過 runserver 命令的方式,那簡單,在啟動 runserver 指令后追加 --insecure 選項能參數強制 django 處理靜態文件。
其他方式啟動
但如果是通過 uwsgi 或 daphne 等啟動的話,追加選項的方式就不管用了。要解決這個問題,我們要手動去使用靜態文件服務,這種處理方式是比較推薦的,因為它同時也支持了 runserver 的方式。
解決的方式如下,在 urls.py 中添加 url 規則:
1
2
3
4
5
6
7
8
9
10
|
from
django.contrib.staticfiles.views
import
serve
from
django.urls
import
re_path
def
return_static(request, path, insecure
=
True
,
*
*
kwargs):
return
serve(request, path, insecure,
*
*
kwargs)
urlpatterns
=
[
...
re_path(r
'^static/(?P<path>.*)$'
, return_static, name
=
'static'
),
# 添加這行
]
|
這樣就行了。
為什么這樣就能解決了?
需要去做靜態文件的路由匹配,但重點是這里多了個函數 return_static 去代理了 serve ,如果你稍微看下 serve 函數的代碼就立馬理解了:
1
2
3
|
def
serve(request, path, insecure
=
False
,
*
*
kwargs):
if
not
settings.DEBUG
and
not
insecure:
raise
Http404
|
默認情況下 insecure=False ,並且在關閉調試模式后都是 404。通過寫個 return_static 函數其實與 --insecure 的選項是異曲同工的。
媒體文件的處理
媒體文件的處理當然可以將上面 url 規則變動下就能加載了。如果用上面的方法來處理媒體文件可以得 90 分,那么下面的方法可以得 95 分。
上面的方法會搜索多個目錄的,盡管開發人員會將靜態文件同一放目錄下。但 Django 的 admin 模塊的靜態文件存放在其他地方的。
而媒體文件,我們只會限定在一個目錄的,所以更好的處理方法是只在一個目錄下搜索:
1
2
3
4
5
6
7
|
from
django.views.static
import
serve as static_serve
# 注意這里引入的與上面的不同
from
django.urls
import
re_path
urlpatterns
=
[
...
re_path(r
'^media/(?P<path>.*)$'
, static_serve, {
'document_root'
: settings.MEDIA_ROOT}),
]
|
另外,如果網站的所有靜態文件都只會在一個目錄下(使用 collectstatic 能將所有靜態文件都復制到一個目錄),那么也請用這個 static_serve 方式去處理靜態文件,我們希望我們的程序是精益求精的良品。
總結
另外還有通過第三方程序來處理靜態文件,比如 nginx 設置 alias 等。但顯然我更希望是程序自身的處理方式。