Django使用Uploadify組件實現圖片上傳

Uploadify組件上傳文件很酷,能夠實現文件進度上傳,並且能夠批量上傳各類文件。好處還不少,具體詳情登到官網看看文檔瞭解吧。在同類組件中,Uploadify作的也很出色。打算在Django中用它,兩個東西結合使用,也算簡單,但有些細節須要記下來,以便之後重用。

此次只說上傳圖片部分,至於上傳文件,其實能夠照貓畫虎,並且來得會簡單些,只是python程序後端寫法的區別而已,前端代碼Uploadify一概平等對待,圖片也是文件一種特例罷了。

Django使用Uploadify組件實現圖片上傳,能夠分爲兩個大步驟。
一:前端引用Uploadify所須要的類庫和腳本樣式。
Uploadify會用到JQuery類庫,還有本身的幾個腳本和樣式文件,搭配好了Django的靜態文件,讓Django正確解析靜態文件,就算成功一半了,靜態文件的配置參考先前的博客:《Django靜態文件的配置》。

靜態文件咱們統一存放在根目錄的site_media文件夾下,到官網http://www.uploadify.com/下載Uploadify-2.14組件,放在site_media下的plugin,隨意起名:uploadify_214,再新建個文件下upload,來存放上傳的圖片。

前端樣式腳本引用代碼:javascript

  1. <link href="/site_media/plugin/uploadify_214/uploadify.css" type="text/css" rel="stylesheet" />  
  2. <script type="text/javascript" src="/site_media/js/jquery.js"></script>  
  3. <script type="text/javascript" src="/site_media/plugin/uploadify_214/swfobject.js"></script>  
  4. <script type="text/javascript" src="/site_media/plugin/uploadify_214/jquery.uploadify.v2.1.4.min.js"></script>  
引用文件的路徑算是很重要,具體靜態配置決定這些。首先引用Uploadify的樣式文件,而後就是先引用JQuery類庫,再引用Uploadify自身腳本swfobject.js和jquery.uploadify.v2.1.4.min.js

Uploadify組件初始化代碼:
  1. <script type="text/javascript">  
  2. $(document).ready(function() {  
  3.   $('#file_upload').uploadify({  
  4.     'uploader'  : '/site_media/plugin/uploadify_214/uploadify.swf',  
  5.     'script'    : '{%url uploadify_script%}',  
  6.     'cancelImg' : '/site_media/plugin/uploadify_214/cancel.png',  
  7.     'folder'    : '/upload',  
  8.     'auto'      : false,//  
  9.     'multi'true,//設置能夠上傳多個文件  
  10.     'queueSizeLimit':20,//設置能夠同時20個文件  
  11.     'removeCompleted':false,//  
  12.     'sizeLimit':10240000,//設置上傳文件大小單位kb  
  13.     'fileExt':'*.jpg;*.gif;*.png',//設置上傳文件類型爲經常使用圖片格式  
  14.     'fileDesc':'Image Files',                  
  15.     'onInit'function () {},  
  16.     'onError' : function (event,ID,fileObj,errorObj) {  
  17.             $('#id_span_msg').html("上傳失敗,錯誤碼:"+errorObj.type+" "+errorObj.info);  
  18.         },  
  19.     'onSelect'function (e, queueId, fileObj) {  
  20.         $('#id_span_msg').html("");  
  21.     },  
  22.     'onAllComplete'function (event, data) {  
  23.         if(data.filesUploaded>=1){  
  24.           $('#id_span_msg').html("上傳成功!");  
  25.         }                      
  26.     }                  
  27.   });  
  28. });  
  29. </script>  
初始化腳本,有幾個關鍵的參數須要說明一下:
uploader是組件須要flash編譯文件,裏面封裝了Uploadify核心的處理程序。
script是後端上傳文件程序的url,這個是後面說的,須要本身寫。
folder是上傳文件的目錄,這裏咱們不計劃使用它,隨便寫一個充數。

前端html代碼css

  1. <h1>Uploadify組件上傳方式</h1>  
  2. <div class="demo-box">  
  3.     <input id="file_upload" type="file" name="Filedata">  
  4.     <div id="file_uploadQueue" class="uploadifyQueue"></div>  
  5.     <p><a href="javascript:$('#file_upload').uploadifyUpload()">上傳圖片</a>  
  6.     <a href="javascript:$('#file_upload').uploadifyClearQueue()">取消上傳</a>  
  7.     </p>  
  8.     <p><span id="id_span_msg"></span></p>  
  9. </div>  

二:寫好後端圖片上傳的方法。
若是剛開始就把寫好的上傳程序和Uploadify結合,也許不是很明智的作法,由於過程當中遇到問題,咱們不很肯定是後端程序的bug仍是Uploadify的配置錯誤,因此建議先把寫好的後端上傳程序,用傳統的上傳方式,去測試,把程序調試好了,再和Uploadify結合,這樣就會很清楚是那塊出現問題了。
因此咱們先寫個通用的上傳函數_upload,用傳統的上傳方式測試它,該函數:
  1. def _upload(file):  
  2.     '''''圖片上傳函數'''  
  3.     if file:              
  4.         path=os.path.join(settings.MEDIA_ROOT,'upload')  
  5.         file_name=str(uuid.uuid1())+".jpg"        
  6.         path_file=os.path.join(path,file_name)  
  7.         parser = ImageFile.Parser()    
  8.         for chunk in file.chunks():    
  9.             parser.feed(chunk)    
  10.         img = parser.close()  
  11.         try:  
  12.             if img.mode != "RGB":  
  13.                 img = img.convert("RGB")  
  14.             img.save(path_file, 'jpeg',quality=100)  
  15.         except:  
  16.             return False  
  17.         return True  
  18.     return False  

這個程序接收一個Files對象,在內存裏處理保存好圖片,程序就幾行代碼就不解釋太多了。大致是先構造一個物理地址用於保存圖片,再把內存裏的圖片信息存入img臨時變量中,判斷圖片的模式,若是不是RGB,轉換,保存成jpg格式,返回True,失敗返回False。
該函數測試經過了,能完成保存圖片的使命,最後就是寫Uploadify須要的函數uploadify_script
  1. @csrf_exempt  
  2. def uploadify_script(request):  
  3.     response=HttpResponse()  
  4.     response['Content-Type']="text/javascript"  
  5.     ret="0"          
  6.     file = request.FILES.get("Filedata",None)          
  7.     if file:              
  8.         if _upload(file):  
  9.             ret="1"  
  10.         ret="2"  
  11.     response.write(ret)  
  12.     return response  

Uploadify使用uploadify_script函數,經過Get方式把圖片控件的信息提交給該函數,函數返回"text/javascript"的內容類型,若是成功寫入字符1,不然寫入非1字符。頁面的圖片控件命名Filedata,Django經過file = request.FILES.get("Filedata",None)獲取控件的圖片信息,若是不是空的,就傳遞給剛纔說的通用函數_upload,保存圖片。


整個過程算是完結了,過程當中值得注意的:
1 經常出現IO Error,若是咱們已經測試_upload和uploadify_script後端程序,他們都沒有錯誤,不少程度上是由於前端的Uploadify初始化腳本的問題,確認Uploadify幾個關鍵的參數能不能正確解析,或者是靜態文件配置沒成功形成的。
2 Forbidden (403)這是Django引起的,Django1.3引進了CSRF,咱們須要進行一些處理,給uploadify_script一個裝飾器@csrf_exempt,記住這個很關鍵,很折騰人。
3 cannot write mode P as JPEG,這個是後端上傳程序的錯誤,是由於上傳了非jpg類型的圖片,咱們須要須要轉換成RGB,再保存,上面已經提過。


好了不廢話,例行給一個例子,看源碼就明白了,本地瀏覽地址:http://127.0.0.1:8000/uploadify/html

相關文章
相關標籤/搜索