本文實例講述了Django實現圖片文字同時提交的方法。分享給大家供大家參考。具體分析如下:
jQuery為我們網站開發解決了很多問題,使我們的網站用戶體驗大大的提高了。舉個簡單的例子,我們用AJAX技術來實現對表單的異步提交,使用戶在體驗上有了很大的改觀,用戶在提交數據的同時還可以干一些其他的事情。
不過,今天在開發中遇到一個特別頭痛的問題,剛開始不知道,以為可以實現,糾結了將近4個小時之久,但結果很是令人失望。
問題是這樣的:為了提高用戶體驗,我決定使用AJAX異步提交,於是我用jQuery的$.post去異步提交表單數據,文本信息可以很輕松的提交,但是,卻怎麼也無法提交圖片數據。怎麼辦呢?
在網上查了很多資料,後來發現jQuery不支持圖片上傳(附件上傳),但是有相關的插件,於是我開始慢慢琢磨,開始用另一個專門上傳文件的插件jquery.ajaxfileupload.js,折騰了很久,總可以上傳圖片了。但是新的問題有產生了。
通過ajaxfileupload來異步上傳圖片的同時,卻不能提交文本數據。囧啊…….
在網上查了很多資料,折騰了許久,沒有Django開發的相關資料,怎麼辦?自己想辦法…….
後來找到了解決方案,跟大家分享一下:
思路:
由於使用jquery.ajaxfileupload.js插件不能傳遞自定義的參數,腫麼辦?自己改寫插件呗。碰巧,網上有別人改過的現成代碼,二話不說,先拿來試試。以下即是我試驗的過程。
1. 前台頁面(部分代碼):
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <table border="0" width="100%"> <form action="." method="post" id="annex_form_2"></form> <tbody> <tr> <td class="col_name" nowrap="nowrap" width="26%">證書名稱:</td> <td width="64%"><input size="65" class="input_general" id="prove_name_2" maxlength="50" name="prove_name" type="text"></td> <td nowrap="nowrap" width="7%"></td> <td nowrap="nowrap" width="3%"><a href="javascript:void(0);" onclick="SubmitAnnexInfo(2)" title="保存"><img src="/static/img/hr_manage/btn_save.gif" alt="點此保存"></a></td> </tr> <tr> <td class="col_name">證件類型:</td> <td><select id="prove_type_2" name="prove_type"> <option selected="selected" value="1">身份證</option> <option value="2">學位證</option> <option value="3">其他證</option> </select></td> <td> </td> <td> </td> </tr> <tr> <td class="col_name">證書描述:</td> <td><input size="80" class="input_general" id="prove_desc_2" maxlength="60" name="prove_desc" type="text"></td> <td> </td> <td> </td> </tr> <tr> <td class="col_name">附件地址:</td> <td><input size="45" class="input_general" id="prove_url_2" maxlength="45" name="prove_url" style="border:0px;" type="file"></td> <td> </td> <td> </td> </tr> <tr> <td colspan="4"> <hr> </td> </tr> </tbody> </table>2. 更改後的jquery.ajaxfileupload.js:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 jQuery.extend({ createUploadIframe: function(id, uri) { //create frame var frameId = 'jUploadFrame' + id; if(window.ActiveXObject) { var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />'); if(typeof uri== 'boolean'){ io.src = 'javascript:false'; } else if(typeof uri== 'string'){ io.src = uri; } } else { var io = document.createElement('iframe'); io.id = frameId; io.name = frameId; } io.style.position = 'absolute'; io.style.top = '-1000px'; io.style.left = '-1000px'; document.body.appendChild(io); return io }, createUploadForm: function(id, fileElementId, data) { //create form var formId = 'jUploadForm' + id; var fileId = 'jUploadFile' + id; var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>'); var oldElement = $('#' + fileElementId); var newElement = $(oldElement).clone(); $(oldElement).attr('id', fileId); $(oldElement).before(newElement); $(oldElement).appendTo(form); //增加文本參數的支持 if (data) { for (var i in data) { $('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form); } } //set attributes $(form).css('position', 'absolute'); $(form).css('top', '-1200px'); $(form).css('left', '-1200px'); $(form).appendTo('body'); return form; }, ajaxFileUpload: function(s) { // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout s = jQuery.extend({}, jQuery.ajaxSettings, s); var id = new Date().getTime() var form = jQuery.createUploadForm(id, s.fileElementId, s.data); var io = jQuery.createUploadIframe(id, s.secureuri); var frameId = 'jUploadFrame' + id; var formId = 'jUploadForm' + id; // Watch for a new set of requests if ( s.global && ! jQuery.active++ ) { jQuery.event.trigger( "ajaxStart" ); } var requestDone = false; // Create the request object var xml = {} if ( s.global ) jQuery.event.trigger("ajaxSend", [xml, s]); // Wait for a response to come back var uploadCallback = function(isTimeout) { var io = document.getElementById(frameId); try { if(io.contentWindow) { xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null; xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document; }else if(io.contentDocument) { xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null; xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document; } }catch(e) { jQuery.handleError(s, xml, null, e); } if ( xml || isTimeout == "timeout") { requestDone = true; var status; try { status = isTimeout != "timeout" ? "success" : "error"; // Make sure that the request was successful or notmodified if ( status != "error" ) { // process the data (runs the xml through httpData regardless of callback) var data = jQuery.uploadHttpData( xml, s.dataType ); // If a local callback was specified, fire it and pass it the data if ( s.success ) s.success( data, status ); // Fire the global callback if( s.global ) jQuery.event.trigger( "ajaxSuccess", [xml, s] ); } else jQuery.handleError(s, xml, status); } catch(e) { status = "error"; jQuery.handleError(s, xml, status, e); } // The request was completed if( s.global ) jQuery.event.trigger( "ajaxComplete", [xml, s] ); // Handle the global AJAX counter if ( s.global && ! --jQuery.active ) jQuery.event.trigger( "ajaxStop" ); // Process result if ( s.complete ) s.complete(xml, status); jQuery(io).unbind() setTimeout(function() { try { $(io).remove(); $(form).remove(); } catch(e) { jQuery.handleError(s, xml, null, e); } }, 100) xml = null } } // Timeout checker if ( s.timeout > 0 ) { setTimeout(function(){ // Check to see if the request is still happening if( !requestDone ) uploadCallback( "timeout" ); }, s.timeout); } try { // var io = $('#' + frameId); var form = $('#' + formId); $(form).attr('action', s.url); $(form).attr('method', 'POST'); $(form).attr('target', frameId); if(form.encoding) { form.encoding = 'multipart/form-data'; } else { form.enctype = 'multipart/form-data'; } $(form).submit(); } catch(e) { jQuery.handleError(s, xml, null, e); } if(window.attachEvent){ document.getElementById(frameId).attachEvent('onload', uploadCallback); } else{ document.getElementById(frameId).addEventListener('load', uploadCallback, false); } return {abort: function () {}}; }, uploadHttpData: function( r, type ) { var data = !type; data = type == "xml" || data ? r.responseXML : r.responseText; // If the type is "script", eval it in global context if ( type == "script" ) jQuery.globalEval( data ); // Get the JavaScript object, if JSON is used. if ( type == "json" ) eval( "data = " + data ); // evaluate scripts within html if ( type == "html" ) jQuery("<div>").html(data).evalScripts(); //alert($('param', data).each(function(){alert($(this).attr('value'));})); return data; } })3. 調用方法
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 //保存附件信息 function SaveAnnexInfo() { var prove_name = $("#id_prove_name").val(); //從界面得到值 var prove_type = $("#id_prove_type").val(); var prove_desc = $("#id_prove_desc").val(); $.ajaxFileUpload({ url: "/test/annex_info /", //請求的Url地址 secureuri:false, fileElementId:'id_prove_url', dataType: 'json', data: { //加入的文本參數 "prove_name":prove_name, "prove_type":prove_type, "prove_desc":prove_desc }, success: function(data) { asyncbox.tips('操作成功!', 'success'); }, error: function() { asyncbox.tips("上傳失敗,請檢查文件是否符合格式要求。"); } }); }4. Python後台處理(代碼片段)
?
1 2 3 4 5 6 7 8 9 if annex_form.is_valid(): annex_info = annex_form.save(commit=False) #獲取上傳 annex_url = request.FILES.get('prove_url','') #取附件 annex_info.entry = entry_info annex_info.prove_url = annex_url annex_info.save() return HttpResponse(1) #操作成功 return HttpResponse(0) #操作失敗希望本文所述對大家的Python程序設計有所幫助。