靜態文件指像css,js,images之類的文件,在Django裏面靜態文件的處理與一般的視圖是不一樣,新手往往容易犯迷糊,本文做一下總結:
一、概述:
靜態文件交由Web服務器處理,Django本身不處理靜態文件。簡單的處理邏輯如下(以nginx爲例):
URI請求-----> 按照Web服務器裏面的配置規則先處理,以nginx爲例,主要求配置在nginx.conf裏的location
|---------->如果是靜態文件,則由nginx直接處理
|---------->如果不是則交由Django處理,Django根據urls.py裏面的規則進行匹配
以上是部署到Web服務器後的處理方式,爲了便於開發,Django提供了在開發環境的對靜態文件的處理機制,方法是這樣:
1、在INSTALLED_APPS裏面加入'django.contrib.staticfiles',
2、在urls.py裏面加入
- if settings.DEBUG:
- urlpatterns += patterns('', url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT }),
- url(r'^static/(?P<path>.*)$','django.views.static.serve',{'document_root':settings.STATIC_ROOT}), )
3、這樣就可以在開發階段直接使用靜態文件了。
二、MEDIA_ROOT和MEDIA_URL
而靜態文件的處理又包括STATIC和MEDIA兩類,這往往容易混淆,在Django裏面是這樣定義的:
MEDIA:指用戶上傳的文件,比如在Model裏面的FileFIeld,ImageField上傳的文件。如果你定義
MEDIA_ROOT=c:\temp\media,那麼File=models.FileField(upload_to="abc/"),上傳的文件就會被保存到c:\temp\media\abc
舉個例子:
- class blog(models.Model):
- Title=models.charField(max_length=64)
- Photo=models.ImageField(upload_to="photo")
上傳的圖片就上傳到c:\temp\media\photo,而在模板中要顯示該文件,則在這樣寫{{MEDIA_URL}}blog.Photo
在settings裏面設置的MEDIA_ROOT必須是本地路徑的絕對路徑,一般是這樣寫
- PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
- MEDIA_ROOT=os.path.join(PROJECT_PATH,'media/').replace('\\','/')
MEDIA_URL是指從瀏覽器訪問時的地址前綴,舉個例子:
- MEDIA_ROOT=c:\temp\media\photo
- MEDIA_URL="/data/" #可以隨便設置
在開發階段,media的處理由django處理:
訪問http://localhost/data/abc/a.png就是訪問c:\temp\media\photo\abc\a.png
在模板裏面這樣寫<img src="{{MEDIA_URL}}abc/a.png">
在部署階段最大的不同在於你必須讓web服務器來處理media文件,因此你必須在web服務器中配置,以便能讓web服務器能訪問media文件
以nginx爲例,可以在nginx.conf裏面這樣:
location ~/media/{
root /temp/
break;
}
具體可以參考如何在nginx部署django的資料。
三、STATIC_ROOT和STATIC_URL、
STATIC主要指的是如css,js,images這樣文件,在settings裏面可以配置STATIC_ROOT和STATIC_URL,配置方式與MEDIA_ROOT是一樣的,但是要注意
STATIC_ROOT與MEDIA_ROOT位置不能一樣。
STATIC文件一般保存在以下位置:
1、STATIC_ROOT:在settings裏面設置,一般用來放一些公共的js,css,images等。
2、app的static文件夾,在每個app所在文夾均可以建立一個static文件夾,然後當運行collectstatic時,Django會遍歷INSTALL_APPS裏面所有app的static文件夾,將裏面所有的文件複製到STATIC_ROOT。因此,如果你要建立可複用的app,那麼你要將該app所需要的靜態文件放在static文件夾中。
也就是說一個項目引用了很多app,那麼這個項目所需要的css,images等靜態文件是分散在各個app的static文件的,比較典型的是admin應用。
當你要發佈時,需要將這些分散的static文件收集到一個地方就是STATIC_ROOT。
3、STATIC文件還可以配置STATICFILES_DIRS,指定額外的靜態文件存儲位置。
STATIC_URL的含義與MEDIA_URL類似。
四、小結
如果你發生在部署階段找不到css,js,則可能是以下幾個問題:
1、web服務器配置有問題,不同的部署方式對靜態文件的處理有所不同。
2、沒有運行collectstatic將所需要的靜態文件收集到STATIC_ROOT
===============
- MEDIA_ROOT:主要是爲了存放上傳的文件,比如在ImageField中,這個值加上upload_to的值就是真實存放上傳圖片的文件位置;Django裏邊文件內容實際上是不會存放到數據庫裏邊的,大多數數據庫存放數據效率低,需要保存在文件系統裏。PS:FileUploads(用來存儲文件)
- MEDIA_URL:URL的映射,前後要加上‘/’ 表示從根目錄開始,比如“/site_media/”,加上這個屬性之後,靜態文件的鏈接前面會加上這個值。
- STATIC_ROOT:在這個文件裏邊的目錄會當成靜態文件處理。但是不能把自己辛苦寫的Javascript或者圖片等靜態文件放進去。
- STATIC_URL:URL映射,指定靜態目錄的URL,默認的是"/static/"。
- STATICFILES_DIRS:指定一個工程裏邊哪個目錄存放了與這個工程相關的靜態文件,是一個列表。如果列表中有一個是 “/home/shishang/test/static”,其中有一個文件內容是productlist.html, 我們只要訪問http://localhost:8000/static/productlist.html就可以直接訪問界面了。
- 轉:Django提供了一個方法自動地將所有的靜態文件放在一起。只要在寫App的時候創建一個static子目錄專門保存靜態文件就行了。在開發階段,不必費心去做映射,不需要配置
urls.py
。在佈署到生產環境的時候,只需要配置Apache把/static/
映射到STATIC_ROOT
。然後運行manage.py collectstatic
,自動地STATICFILES_DIRS
列出的目錄以及各個App下的static子目錄的所有文件複製到STATIC_ROOT。因爲複製過程可能會覆蓋掉原來的文件,所以,一定不能把我們辛苦做出來靜態文件放這邊!在開發階段,Django把/static
映射到django.contrib.staticfiles
這個App。staticfiles
自動地從STATICFILES_DIRS
、STATIC_ROOT
以及各個App的static
子目錄裏面搜索靜態文件。一旦佈署到開發環境上,settings.py不需要重新編寫,只要在Apache的配置文件裏面寫好映射,/static
將會被Apache處理。django.contrib.staticfiles
雖然仍然存在,但因爲不會接收到以/static/
開始的路徑,所以將不會產生作用。不必擔心Django會使用處理速度變慢。另外,當settings.DEBUG is False
的時候,staticfiles
將自動關閉。 - 具體代碼示例:
- #setting.py 中加入:
- import os
- HERE = os.path.dirname(os.path.dirname(__file__))
- MEDIA_ROOT = os.path.join( HERE, "../media").replace('\\', '/')
- MEDIA_URL = "/site_media/"
- STATIC_ROOT = os.path.join(HERE, "../static").replace('\\', '/')
- STATIC_URL = "/static/"
- STATICFILES_DIRS = ( os.path.join(HERE, "../app名字/static/").replace('\\', '/'), ) #和STATIC_ROOT最好路徑不要重疊
- #建議將靜態文件保存在app的static目錄中
- #urls.py中加入:
- from django.conf.urls.static import static
- from django.conf import settings
- urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
- urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
- #這樣使用
- <link type="text/css" rel="stylesheet" href="/static/css/bootstrap.min.css"/>
- <link type="text/css" rel="stylesheet" href="/static/css/bootstrap-responsive.css"/>