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
- <link href="/site_media/plugin/uploadify_214/uploadify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="/site_media/js/jquery.js"></script>
- <script type="text/javascript" src="/site_media/plugin/uploadify_214/swfobject.js"></script>
- <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組件初始化代碼:
- <script type="text/javascript">
- $(document).ready(function() {
- $('#file_upload').uploadify({
- 'uploader' : '/site_media/plugin/uploadify_214/uploadify.swf',
- 'script' : '{%url uploadify_script%}',
- 'cancelImg' : '/site_media/plugin/uploadify_214/cancel.png',
- 'folder' : '/upload',
- 'auto' : false,
- 'multi': true,
- 'queueSizeLimit':20,
- 'removeCompleted':false,
- 'sizeLimit':10240000,
- 'fileExt':'*.jpg;*.gif;*.png',
- 'fileDesc':'Image Files',
- 'onInit': function () {},
- 'onError' : function (event,ID,fileObj,errorObj) {
- $('#id_span_msg').html("上傳失敗,錯誤碼:"+errorObj.type+" "+errorObj.info);
- },
- 'onSelect': function (e, queueId, fileObj) {
- $('#id_span_msg').html("");
- },
- 'onAllComplete': function (event, data) {
- if(data.filesUploaded>=1){
- $('#id_span_msg').html("上傳成功!");
- }
- }
- });
- });
- </script>
初始化腳本,有幾個關鍵的參數須要說明一下:
uploader是組件須要flash編譯文件,裏面封裝了Uploadify核心的處理程序。
script是後端上傳文件程序的url,這個是後面說的,須要本身寫。
folder是上傳文件的目錄,這裏咱們不計劃使用它,隨便寫一個充數。
前端html代碼css
- <h1>Uploadify組件上傳方式</h1>
- <div class="demo-box">
- <input id="file_upload" type="file" name="Filedata">
- <div id="file_uploadQueue" class="uploadifyQueue"></div>
- <p><a href="javascript:$('#file_upload').uploadifyUpload()">上傳圖片</a>
- <a href="javascript:$('#file_upload').uploadifyClearQueue()">取消上傳</a>
- </p>
- <p><span id="id_span_msg"></span></p>
- </div>
二:寫好後端圖片上傳的方法。
若是剛開始就把寫好的上傳程序和Uploadify結合,也許不是很明智的作法,由於過程當中遇到問題,咱們不很肯定是後端程序的bug仍是Uploadify的配置錯誤,因此建議先把寫好的後端上傳程序,用傳統的上傳方式,去測試,把程序調試好了,再和Uploadify結合,這樣就會很清楚是那塊出現問題了。
因此咱們先寫個通用的上傳函數_upload,用傳統的上傳方式測試它,該函數:
- def _upload(file):
- ''
- if file:
- path=os.path.join(settings.MEDIA_ROOT,'upload')
- file_name=str(uuid.uuid1())+".jpg"
- path_file=os.path.join(path,file_name)
- parser = ImageFile.Parser()
- for chunk in file.chunks():
- parser.feed(chunk)
- img = parser.close()
- try:
- if img.mode != "RGB":
- img = img.convert("RGB")
- img.save(path_file, 'jpeg',quality=100)
- except:
- return False
- return True
- return False
這個程序接收一個Files對象,在內存裏處理保存好圖片,程序就幾行代碼就不解釋太多了。大致是先構造一個物理地址用於保存圖片,再把內存裏的圖片信息存入img臨時變量中,判斷圖片的模式,若是不是RGB,轉換,保存成jpg格式,返回True,失敗返回False。
該函數測試經過了,能完成保存圖片的使命,最後就是寫Uploadify須要的函數uploadify_script
- @csrf_exempt
- def uploadify_script(request):
- response=HttpResponse()
- response['Content-Type']="text/javascript"
- ret="0"
- file = request.FILES.get("Filedata",None)
- if file:
- if _upload(file):
- ret="1"
- ret="2"
- response.write(ret)
- 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
![](http://static.javashuo.com/static/loading.gif)