我正在使用django 1.5,python 2.7和jquery 1.9。我有一个表格,它有两个字段,即标题和文件。当我按提交时,我希望用户选择的文档出现在request.FILES中,如视图中所示。
当我提交常规表单(没有ajax)时,这样可以正常工作,但是使用ajax我在请求中没有得到文件字段。有关如何使用ajax 上传文件的任何建议。
HTML:
<form enctype="multipart/form-data" action="{% url 'upload_document' %}" method="post" id="uploadForm">
{% csrf_token %}
<ul>
<li>
<div>Title</div>
<input id="title" type="text" maxlength="200"/>
<div class="error"></div>
</li>
<li>
<div>Upload File</div>
<input id="document" type="file" size="15" />
<div class="error"></div>
</li>
</ul>
<input type="submit" value="submit"/></p>
</form>
FORMS.PY:
class UploadForm( forms.Form ):
document = forms.FileField()
title = forms.CharField(max_length = 200)
def clean(self):
cleaned_data = super(UploadForm, self).clean()
return cleaned_data
def save(self, *args, **kwargs):
title = self.cleaned_data['title']
doc = self.cleaned_data['document']
document = Document(title = title, document = doc)
document.save()
return document
SCRIPT:
<script type="text/javascript">
$("#uploadForm").submit(function(event){
event.preventDefault();
$.ajax({
url : "{% url 'upload_document' %}",
type: "POST",
data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
title: document.getElementById('title').value,
//document: document: document.getElementById('document'),
},
dataType : "json",
success: function( response ){
if(response == "True"){
// success
}
else {
//append errors
}
}
});
});
</script>
VIEWs.PY
def upload_document(request):
print request.POST
print request.FILES
if request.is_ajax():
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
form.save()
return HttpResponse(simplejson.dumps('True'), mimetype = 'application/json' )
else:
errors = form.errors
return HttpResponse(simplejson.dumps(errors), mimetype = 'application/json' )
答案 0 :(得分:3)
这个问题的答案并不那么简单。首先,如果你打算支持旧的浏览器,那么它确实很糟糕。你必须处理隐藏的iframe和一些JavaScript技巧。我建议使用一些众所周知的脚本,如jQuery-File-Upload。
但世界正在发展,包括HTML5在内的新技术也在不断涌现。有一个新的File API可用于大多数现代浏览器(IE10 +,FireFox3.6 +,Chrome13 +,请参阅:http://caniuse.com/fileapi),可用于此目的。首先,您需要一些HTML:
<input type="file" id="file-select" />
然后你可以绑定到(例如)change
事件:
$('#file-select').change( handleFileSelect );
最后是处理程序本身:
var data = {};
function createReaderHandler(name) {
return function(ev) {
data[name] = ev.target.result;
};
}
function handleFileSelect(ev) {
var files = ev.target.files; // FileList object
// Loop through the FileList
for (var i = 0; i < files.length; i++) {
var file = files[i],
name = file.name || file.fileName,
reader = new FileReader();
reader.onload = createReaderHandler(name);
reader.readAsText(file);
}
}
将数据加载到JavaScript内存后(注意操作异步),您可以像任何其他数据一样通过AJAX发送数据。还有更多选项:根据您的文件,您可以使用.readAsBinaryString
将其作为二进制数据读取,依此类推。谷歌是你的朋友。 :)
另外我认为已经有很好的脚本用于上传文件并回退到旧方法。这个可能很有趣(没试过):
答案 1 :(得分:0)
我认为问题在于提交按钮,将其更改为普通按钮
即,<button type='button' id='submit'>submit</button>
(默认情况下,表单中的所有按钮都是提交的)
和ajax一样
$('#submit').on('click',function(){
frm = $(this).parents('form')
$.ajax({
type: frm.attr('method'),
dataType:'json',
url: frm.attr('action'),
data: frm.serialize(),
async: false,
success: function (data) {
console.log('success')
},
error: function(data) {
console.log("Something went wrong!");
}
})
所有其他人都是一样的 试试它会起作用