Django 項目設置 Debug=False 後靜態文件和上傳文件404錯誤問題解決

注:該方法適用於 Django 項目、靜態文件和上傳文件在同一臺設備中。如靜態文件在專用服務器或使用CDN,請參考 https://docs.djangoproject.com/zh-hans/3.0/howto/static-files/deployment/python

​ 靜態文件和用戶上傳文件的相關配置本文再也不贅述,直入主題吧。nginx

​ 默認配置下,Django 會在 DEBUG=True 時經過 django.contrib.staticfiles app 自動發現靜態文件,用戶上傳文件則須要下面代碼去實現自動配置。shell

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 給了兩種方案。centos

  1. 手動經過 django.views.static.serve() 爲靜態文件和用戶上傳文件配置提供服務。但這種方法不安全。
  2. 結合 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 beginapp

  • 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_ROOTMEDIA_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 中便可正常顯示。

【完】

相關文章
相關標籤/搜索