使用django實現網頁的時候,想要在網頁上顯示圖片是一件比較麻煩的事情。標准的html語言顯示圖片的方法在這里行不通,需要在配置文件中稍作修改。
那么我們可以非常自然想到,網頁上的圖片的來源方式有兩種。1種是靜態圖片,即在寫網頁的時候就確定好頁面上要放那一張圖片。1種是動態圖片,如從數據庫中的查詢得到的圖片。這兩種顯示圖片的方式稍有不同,以下分兩個部分進行說明。
寫在前面:我在做的是django是1.8的版本號,在ubuntu環境下寫的。
一、靜態圖片
假設我們現在已經有了一個可運行的網站,網站的結構如下所示:
.
├── db.sqlite3
├── image
│ ├── admin.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ ├── models.py
│ ├── templates
│ │ └── index.html
│ ├── tests.py
│ ├── urls.py
│ ├── views.py
├── manage.py
├── showImg
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
└── static
└── 1.jpg
從上述結構可以看出,這個項目的名字叫做“showImg”,而APP的名字叫做“image”。至於其他各個文件的作用我就不再一一贅述,如果對這些文件還不是很明白的話,建議可以先從基本的入手。
在我們的主頁面中,index.html文件希望現實static文件夾下面的這個圖片,目前index.html的內容如下:
<!-- index.html -->
<html> <head><head> <body> <h1>An Image Test</h1> <img src="/static/1.jpg"> </body> </html>
按照傳統的理解,這個時候圖片是可以現實的,但在django中,圖片顯示的是一個“×”,圖片無法顯示出來。
這是因為按照django處理鏈接的習慣,每次django遇到一個鏈接,都會到urls.py中尋找相應的解決方案。而urls.py中也給出各個鏈接對應的views.py文件中的處理函數,所以這個時候我們需要修改urls.py文件。當然,這個urls.py文件是image文件夾下的,而不是showImg文件夾下的。
# ./image/urls.py
from django.conf.urls import patterns, url from image import views urlpatterns = patterns('', url(r'^$', views.show, name='index'), url(r'^static/(?P<path>.*)', 'django.views.static.serve', {'document_root':'/home/anna/Documents/django_py/showImg/static'}), )
標紅的內容就是要新添加的一行說明,告訴django,當遇到一個“static”開頭的鏈接時,改如何處理。
這個時候,再訪問http://127.0.0.1:8000/image/ 發現,圖片還是無法顯示,我們還需要小小的修改一下index.html中的內容
<!-- index.html --> <html> <head><head> <body> <h1>An Image Test</h1> <img src="static/1.jpg"> </body> </html>
這個地方和前面的代碼有什么不同呢?就是圖片路徑不在是絕對路徑而是相對路徑了(呃,其實我也不知道為什么,我也是嘗試了好久才發現應該是這個樣子的。恩。)
這個時候再訪問http://127.0.0.1:8000/image/就沒問題啦!
然后我們又會有一個問題,我習慣把圖片放在別的目錄下面,放在根目錄的static下面不符合我的習慣。這個時候再要修改,也就是非常方便的事情了。
.
├── db.sqlite3
├── image
│ ├── admin.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ ├── models.py
│ ├── templates
│ │ └── index.html
│ ├── pic
│ │ └── 1.jpg
│ ├── tests.py
│ ├── urls.py
│ ├── views.py
├── manage.py
├── showImg
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
└── static
└── 1.jpg
比如說將圖片放在image/pic/目錄下,那么這個是我們首先修改urls.py文件的內容。
# ./image/urls.py from django.conf.urls import patterns, url from image import views urlpatterns = patterns('', url(r'^$', views.show, name='index'), url(r'^image/pic/(?P<path>.*)', 'django.views.static.serve', {'document_root':'/home/anna/Documents/django_py/showImg/image/pic'}), )
注意到綠色高亮的部分,就是把原先的“static”全部都換成了新的路徑。相應的,index.html文件也是一樣的處理方式。
<!-- index.html --> <html> <head><head> <body> <h1>An Image Test</h1> <img src="image/pic/1.jpg"> </body> </html>
這樣再訪問http://127.0.0.1:8000/image/就也可以了
當然,所謂一樣通樣樣通,萬變不離其宗,為了保證接口的一致性,我們也可以保留static關鍵字,而只修改圖片的位置。這個時候的代碼如下:
# ./image/urls.py from django.conf.urls import patterns, url from image import views urlpatterns = patterns('', url(r'^$', views.show, name='index'), url(r'^static/(?P<path>.*)', 'django.views.static.serve', {'document_root':'/home/anna/Documents/django_py/showImg/image/pic'}), )
<!-- index.html --> <html> <head><head> <body> <h1>An Image Test</h1> <img src="static/1.jpg"> </body> </html>
發現其中的不同了嗎?這樣也是可以的哦。
=========================
上面的方法基本可以滿足我們的需要啦,但是因為種種原因,我們選擇另一種方法來解決這個問題。
還是從最基本的說起,項目結構如下,圖片在static文件夾下。
.
├── db.sqlite3
├── image
│ ├── admin.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ ├── models.py
│ ├── templates
│ │ └── index.html
│ ├── tests.py
│ ├── urls.py
│ ├── views.py
├── manage.py
├── showImg
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
└── static
└── 1.jpg
首先需要在showImg/settings.py文件中加一句話
# showImg/settings.py
STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static').replace('\\', '/'), )
紅色的就是添加的話,不用做任何改動(前提是圖片在static文件夾下)。然后再修改index.html的內容:
<!-- index.html --> <html> <head><head> <body> <h1>An Image Test</h1>
{% load staticfiles %} <img src="{% static"1.jpg"%}"> </body> </html>
着重要修改的內容如紅色高亮。這里需要注意的是,img的src的內容中,1.jpg的前后是不能要空格的,否則圖片的路徑將會是錯誤的。
<img src="{% static"1.jpg "%}">
比如上述代碼,這樣的圖片路徑是有錯誤的。
如果大家發現圖片無法顯示的話,可以用“審查元素”看一下圖片的路徑是否正確,正確的圖片路徑應該是:
<img src="/static/1.jpg">
相應的,如果大家不習慣把圖片的內容放到static文件夾下面的話,這里只用改一處就可以了:
# showImg/settings.py STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'image/pic').replace('\\', '/'), )
然后在index.html文件中,還是使用static來訪問圖片。
二、動態圖片
動態圖片的處理過程與靜態圖片沒有根本上的區別。我們還是承接上面的例子來思考,如果用戶上傳的動態圖片就是存儲在/static文件夾下面的,我們怎么辦呢?
. ├── db.sqlite3 ├── image │ ├── admin.py │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ ├── models.py │ ├── templates │ │ └── index.html │ ├── tests.py │ ├── urls.py │ ├── views.py ├── manage.py ├── showImg │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ ├── wsgi.py └── static └── 1.jpg
現在我們假設前面的靜態圖片的目的已經成功了,只不過現在新添加了一個功能,是上傳圖片,並將圖片存儲在/static文件夾下。
這時候我們自然想到,要將上傳的圖片顯示到網頁上,首先要從視圖層(views.py)中將要顯示的圖片信息傳給網頁,假設圖片信息是圖片名稱,即本例中的“1.jpg”,那么views.py的部分代碼為:
# views.py return render_to_response('index.html', {'images':'1.jpg'})
當把要顯示的圖片傳遞給網頁后,index.html的代碼就有所改變了:
<!-- index.html --> <html> <head><head> <body> <h1>An Image Test</h1> {% load staticfiles %} <img src="{% static images %}"> </body> </html>
改變只如紅色高亮部分,將原來的具體的圖片名稱改成了傳遞過來的內容指代。當然,如果在views.py中傳遞過來的圖片不只1張的話,即:
# views.py return render_to_response('index.html', {'images':['1.jpg', '2.jpg']})
如上述代碼,傳遞的是一個list,index.html采用上面的代碼是無法正確顯示出圖片的。通過審查元素看到的圖片的url是亂碼,這個時候我們就要循環顯示圖片了:
<!-- index.html --> <html> <head><head> <body> <h1>An Image Test</h1> {% load staticfiles %}
{% for img in images %} <img src="{% static img %}">
{% endfor %} </body> </html>
這個時候必須如上述代碼中循環顯示圖片才能正確顯示。
===========================
好了,到這里我們已經分別講述了如何顯示靜態和動態的圖片了。但是如果當一個網站里面同時包含靜態和動態的圖片的話,就還是需要使用不同的指代方式——“static”和“media”。static的內容我們已經講過了,如果是動態圖片的話,media如何使用:
# settings.py MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace('\\','/') MEDIA_URL = '/media'
在settings.py中加入如上內容。然后修改online/models.py中的內容,將上傳的圖片顯示到media文件夾下
# online/models.py class Image(models.Model): headImg = models.FileField(upload_to = '.')
其中標紅處的文件路徑是比較關鍵的。這里只寫一個當前路徑,而不再寫文件夾的名稱,是因為在settings.py文件中已經指定了上傳文件的位置,就是在/media 文件夾下,所以這里不用再指定了。如果在這里寫成
# online/models.py class Image(models.Model): headImg = models.FileField(upload_to = './media')
就會發現,上傳的圖片其實是保存在/media/media文件夾下面的。
這時,再將圖片信息傳遞給頁面,讓頁面顯示,就可以了:
<!-- index.html --> <html> <head><head> <body> <h1>An Image Test</h1> {% load staticfiles %} {% for img in images %} <img src="{% static img %}"> {% endfor %} </body> </html>
注意,這里依然用static作為關鍵字,而不因為是動態文件就用media之類的。
Bon Appetite!