本文实例讲述了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程序设计有所帮助。