解決uWSGI里的Django靜態文件丟失


uWSGI來單獨運行一個Django應用,有一個static文件丟失的大坑。 本文介紹如何出坑。

(本文針對的Django版本在1.4以上,因為1.3以前有ADMIN_MEDIA_PREFIX這個坑,本文並不涉及。)

問題

一個Django應用,在./manage.py runserver情況下,正常運行。 而在uWSGI運行的情況下,則網頁樣式奇怪,靜態文件找不到。

也就是說,調試的情況下沒問題,生產環境找不到靜態文件。

(假如在runserver的調試環境下也有問題,則通常是配置有誤。 本文不討論配置錯誤的情況。)

以下舉例說明。

settings.py配置中,使用了django.contrib.staticfiles,並且做出以下配置。

BASE_DIR = os.path.dirname(os.path.realpath(__file__))

STATIC_ROOT = '/srv/django/static'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
靜態文件設置

現象為,STATIC_URL位置的文件,在uWSGI下,無法用瀏覽器訪問,而在runserver下則沒問題。

原因

一個Django應用,一般有兩類靜態文件。 一是應用內的靜態文件,二是Django自帶的。

按照前面代碼的示例,應用內的靜態文件在與settings.py同級的static目錄下。

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
應用內static文件

此外,在INSTALLED_APPS中配置了django.contrib.admin, 則還會有另外一組靜態文件,在Django安裝位置里。

例如,一個root在Python 3.6版本安裝的Django,admin的靜態文件在: /usr/local/lib/python3.6/site-packages/django/contrib/admin/static/admin/

最終,在STATIC_URL里,會有兩類靜態文件。 /static/*/static/admin/*

了解原理,原因就很顯然了。 uWSGI根本不知道靜態文件在什么位置。

解決

STATIC_ROOT這個參數,在runserver情況下是無用的,因為Django自己知道位置在哪。

在集成了django.contrib.staticfiles后,./manage.py多了一個子命令。

./manage.py collectstatic

這個子命令,會把所有STATICFILES_DIRS目錄下的文件,都復制到STATIC_ROOT中。 在這里,也就是/srv/django/static目錄下。

uWSGI也是支持靜態文件的,可以通過執行時添加參數:

uwsgi --static-map /static=/srv/django/static

或者,在配置文件中添加:

static-map = /static=/srv/django/static

=前面的/staticuWSGI的URL前綴,而后面的/srv/django/static則是靜態文件的路徑。 這個路徑,通常使用絕對路徑,但也支持相對路徑。

所以,生產環境部署時,解決方案一共分兩步:

  1. 使用collectstatic子命令,收集、復制相關靜態文件。
  2. 啟動uWSGI,其中包含static-map配置、或--static-map參數。

另外,如果是使用Nginx代理,也可以考慮把靜態文件交給它。 這里不做介紹。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM