注:該方法適用於 Django 項目、靜態文件和上傳文件在同一台設備中。如靜態文件在專用服務器或使用CDN,請參考 https://docs.djangoproject.com/zh-hans/3.0/howto/static-files/deployment/
靜態文件和用戶上傳文件的相關配置本文不再贅述,直入主題吧。
默認配置下,Django 會在 DEBUG=True
時通過 django.contrib.staticfiles
app 自動發現靜態文件,用戶上傳文件則需要下面代碼去實現自動配置。
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
然而當 DEBUG=False
后再次訪問項目時,會發現靜態文件和用戶上傳文件(如用戶頭像)均報404錯誤。這是因為該方法對於 DEBUG=False
不適用。
對於靜態文件和用戶上傳文件的部署,Django 給了兩種方案。
- 手動通過
django.views.static.serve()
為靜態文件和用戶上傳文件配置提供服務。但這種方法不安全。 - 結合 Django 項目的部署 ,通過配置 Web 服務器(如:Nginx),使其在
STATIC_URL
下為STATIC_ROOT
目錄下的文件提供靜態文件服務,用戶上傳文件類似。官網推薦使用該方法。
環境
centos 7
nginx = 1.2
django = 2.2
python = 3.7
方案一:手動通過django.views.static.serve()
為靜態文件和上傳文件配置服務
settings.py
中配置靜態文件和上傳文件
# settings.py
DEBUG = False
# 靜態文件
STATIC_URL = '/static/'
STATIC_ROOT=os.path.join(BASE_DIR,"/static/") # 使用 collectstatic后收集的靜態文件的存放絕對路徑
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] # 存放靜態文件的目錄,其中也可以包含url
# 文件上傳
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
project/project/urls.py
中為靜態文件和上傳文件配置URL
# urls.py
from django.urls import path, include, re_path
from django.views.static import serve
from django.conf import settings
urlpatterns = [
...
re_path(r'^static/(?P<path>.*)$', serve, {'document_root': settings.STATIC_ROOT}, name='static'),
re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}, name='media')
]
- 收集靜態文件,並將已發現靜態文件復制到
settings.STATUS_ROOT
目錄中
# 終端
python manage.py collectstatic
- 啟動服務,會發現靜態文件和上傳文件均顯示成功
python manage.py runserver 0:8000
此后,若靜態文件發生改變后再出現404錯誤,再次執行
python manage.py collectstatic
即可
方案二:通過配置 Web 服務器提供靜態文件服務
該方案會涉及 Nginx + uwsgi + Django 的部署(本次為單機部署),本次解決的問題是靜態文件和用戶上傳文件404錯誤問題,部署的相關知識后期會陸續補充。
先看部署框架
我們的目的是當用戶訪問 /static
和 /media
后會正常訪問靜態資源和用戶上傳文件。Let's begin
- Nginx 服務器中新建靜態文件和用戶上傳文件的保存目錄,並修改權限(不修改會爆403錯誤)
mkdir -P /var/www/finance/static
mkdir -P /var/www/finance/media
chmod 777 /var/www/finance/static
chmod 777 /var/www/finance/media
- 修改
settings.py
,將STATOC_ROOT
和MEDIA_ROOOT
設置為 Nginx 服務器中保存靜態文件和用戶上傳文件的位置
# 靜態文件
STATIC_URL = '/static/'
STATIC_ROOT="/var/www/finance/static"
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
# 文件上傳
MEDIA_URL = '/media/'
MEDIA_ROOT = "/var/www/finance/media/"
注意:
MEDIA_ROOT
發生改變后,用戶上傳文件的存放路徑也會隨之改變。如果開發環境中已上傳用戶數據,那么需要將這些數據一並復制到MEDIA_ROOT
下才能保證頁面的正常顯示
- 收集靜態文件,將項目涉及的所有靜態文件收集到
STATIC_ROOT
目錄下
# 終端
python manage.py collectstatic
- 重啟 uwsgi 服務器
uwsgi --stop uwsgi.pid
uwsgi --ini uwsgi.ini
- 配置 Nginx 服務器
/etc/nginx/nginx.conf
...
server {
...
location / {
# 包含uwsgi的請求參數
include /etc/nginx/uwsgi_params;
# 轉交請求給uwsgi
uwsgi_pass 127.0.0.1:8000;
}
location /static {
# 指定靜態文件存放的目錄
alias /var/www/finance/static/;
}
location /media {
# 指定用戶上傳存放目錄
alias /var/www/finance/media/;
}
...
}
配置
/static
和/media
的轉發規則,URL 字段可以根據項目需求自行更改
- 重啟 Nginx 服務,瀏覽器中打開項目,會發現靜態文件和上傳文件均顯示成功
systemctl restart nginx
此后,若靜態文件在項目中發生改變,再次執行
python manage.py collectstatic
將其轉移至STATIC_ROOT
中即可正常顯示。
【完】