Djangon生產環境靜態資源的處理
Django 關閉DEBUG模式后,就相當於是生產環境了。
Django框架一旦作為生產環境,它的靜態文件訪問接口就不應該從Django框架中走,必須在Django框架前端部署nginx或者其他web服務器來提供靜態訪問入口
With debug turned off Django won't handle static files for you any more - your production web server (Apache or something) should take care of that.
nginx配置如下:
server { listen 80; server_name 127.0.0.1 charset UTF-8; access_log /var/log/nginx/django_pro01_access.log; error_log /var/log/nginx/django_pro01_error.log; client_max_body_size 75M; location / { include uwsgi_params; uwsgi_pass 127.0.0.1:8000; uwsgi_read_timeout 2; } # 在nginx中要單獨做訪問/static/目錄的路由 location /static { expires 30d; autoindex on; add_header Cache-Control private; alias /usr/share/nginx/django_pro01/static/; } }
所有靜態文件都應該從“/usr/share/nginx/django_pro01/static/”這個目錄中(也就是上面定義的STATIC_ROOT)獲取。
運行 python manage.py collectstatic 命令的目的,是將在開發模式中定義的靜態目錄,統一拿到STATIC_ROOT目錄下,對外提供“/static”(STATIC_URL)為訪問URL:
1.首先從Django的擴展包中,將admin管理后台的jss 和css等靜態文件拷貝到配置文件中的STATIC_ROOT目錄下。
2.然后將STATICFILES_DIRS 列表中所有目錄下的內容也拷貝到STATIC_ROOT目錄下
最佳實踐
最佳的配置方式是將所有的App 下面的靜態文件統一放置到一個目錄下面,然后將該目錄設置為STATICFILES_DIRS,STATIC_ROOT則設置為另外的目錄:
# 對外提供WEB訪問時的URL地址 STATIC_URL = '/static/' # 開發階段放置項目自己的靜態文件,不能包含STATIC_ROOT路徑 STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'staticfiles'), ) # 執行collectstatic命令后會將項目中的靜態文件(包括STATICFILES_DIRS、自帶admin的靜態文件)收集到該目錄下面來(所以不應該在該目錄下面放置自己的一些靜態文件,因為會覆蓋掉) STATIC_ROOT = os.path.join(BASE_DIR, 'static')
在開發階段Django把/static 映射到django.contrib.staticfiles這個App,django.contrib.staticfiles自動地從STATICFILES_DIRS、STATIC_ROOT以及各個App的static子目錄里面搜索靜態文件。
一旦部署到開發環境上,settings.py不需要重新編寫,只要在Nginx的配置文件里面寫好映射,/static將會被Nginx處理。
django.contrib.staticfiles雖然仍然存在,但因為不會接收到以/static/開始的路徑,所以將不會產生作用。不必擔心Django會使處理速度變慢。
當settings.DEBUG is False的時候,staticfiles將自動關閉。
Django繼續使用靜態資源的辦法
Django在非debug模式下,不處理靜態資源文件,原因可能是性能,使用CDN比較好,但是小應用就不用了,解決辦法:
- python manage.py runserver 0:8088 --insecure
- https://github.com/evansd/whitenoise
- https://github.com/heroku-python/dj-static
在django中使用靜態文件
-
首先確保django.contrib.staticfiles在 INSTALLED_APPS中
- 在settings中定義 STATIC_URL STATIC_URL = '/static/'
- 在你app的static目錄中存放靜態文件,比如:my_app/static/my_app/example.jpg.
- 如果有別的靜態資源文件,不在app下的static目錄下,可以通過 STATICFILES_DIRS來指定額外的靜態文件搜索目錄。
STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static"), ... ]
5. 在模板中使用load標簽去加載靜態文件,通過模板標簽static和給定的相對路徑來構成一個URL
{% load static %}
<img src="{% static "my_app/example.jpg" %}" alt="My image"/>
當然也可以直接使用路徑
<img src="static/my_app/example.jpg" alt="My image"/>
匯集靜態資源到指定目錄
python manage.py collectstatic在執行時,django默認會去查看定義在STATICFILES_DIRS里的目錄,以及在INSTALLED_APPS里定義了的app的static目錄。如果這些目錄下有文件,則把文件全部收集起來,拷貝到STATIC_ROOT目錄下。當使用django的runserver時,如果請求的是一個靜態文件,django也是會默認查看上述的ROOT、DIRS和static目錄。但是,在部署到服務器上時,此規則就不使用了
來源:
http://blog.51cto.com/wenguonideshou/2089955
參考:
https://www.qikqiak.com/post/django-staticroot-staticfilesdirs-function/
http://whitenoise.evans.io/en/stable/base.html
https://blog.csdn.net/G_SANGSK/article/details/80499994
https://zhuanlan.zhihu.com/p/31475023
