Ajax 和 jQuery 实现进度条+上传文件到Django

前端之家收集整理的这篇文章主要介绍了Ajax 和 jQuery 实现进度条+上传文件到Django前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

http://www.laurentluce.com/posts/upload-to-django-with-progress-bar-using-ajax-and-jquery/


本文中我打算描述一下,我如何实现用 Ajax 和 jQuery 实现上传文件到Django+进度条。我需要实现这个功能来让用户上传菜品图片Gourmious并跟踪上传进度。

客户端

首先需要一个表单来让用户选择要上传文件

1 <formid="form_upload"action"/upload"method"POST">
2 inputtype"file"name"picture""picture"/>
3 "hidden""X-Progress-ID"value""/>
4 "id"5 "form_submit_button"class"tp-button""submit""Submit"6 </form>

这里增加了两个隐藏的输入框,第一个是 ‘X-Progress-ID’,代表上传 ID,这样我们才能够在服务器端支持并发的上传请求。稍后我们会看到,服务器是如何处理这个值的。

然后还有一个隐藏输入框 ‘id’,在我们的例子里代表菜品的编号。

我们将使用 Ajax 来发送 POST 请求,这样表单便可以很好地集成在现代的网络界面中,同时包含一个进度条。我们打算使用jQuery Form plugin来实现这一点。

函数 ajaxSubmit() 将会帮我们搞定一切。

上传 ID 生成一个随机字串,并用它设置输入框的值。
需要指定一个用于上传请求的 URL 和两个回调函数:一个在请求前调用,另一个在请求完成后调用

$('#X-Progress-ID').val('random string');
varoptions = {
dataType:'xml',
url:'/upload?X-Progress-ID='+$().val(),
beforeSubmit: showRequest,monospace!important; font-size:1em!important; direction:ltr!important; display:inline!important; background:none!important">success: showResponse
7 }
8 '#form_upload').ajaxSubmit(options);

showRequest 回调函数只需要像下面这么简单就行了:

functionshowRequest(formData,jqForm,options) {
// do something with formData
returnTrue;
}

在 showResponse 函数中,我们需要处理响应,并对它进行操作。在我的例子里,我处理了服务器返回的带有状态值的 xml。

showResponse(response) {
// do something with response
}

用户按下提交的时候,我们希望显示一个进度条,因此可以使用下面的 JS 代码,向表单添加进度条。progressBar() 方法jQuery progress bar plugin的一部分。

).find('#form_submit_input').append('&lt;span id="uploadprogressbar"&gt;&lt;/span&lt;''#uploadprogressbar').progressBar();

现在我们需要添加一个每隔几秒运行一次的函数,来从服务器获取上传进度,并相应地更新进度条。

为此,我们使用 setInterval() 向服务器发出一个 GET 请求,获取 JSON 格式的进度值。我们向服务器传送上传 ID。当返回 null 值的时候,就可以知道上传已经结束。

01 startProgressBarUpdate(upload_id) {
02 "#uploadprogressbar").fadeIn();
03 if(g_progress_intv != 0)
04 clearInterval(g_progress_intv);
05 g_progress_intv = setInterval(() {
06 $.getJSON("/get_upload_progress?X-Progress-ID="
07 + upload_id,(data) {
08 (data ==null) {
09 ).progressBar(100);
10 11 g_progress_intv = 0;
12 ;
13 14 percentage = Math.floor(100 * parseInt(data.uploaded) / parseInt(data.length));
15 ).progressBar(percentage);
16 });
17 },5000);
18 }

服务器端

首先需要 views.py 中有一个函数来处理上传。这个函数处理请求 “/upload?X-Progress-ID=xxxx”。我们将会一块一块地读取文件,以免使用过多 RAM。在我的例子里,我会返回包含状态值的 xml:上传成功或失败。

defupload(request):
id=request.POST['id']
path='/var/www/pictures/%s'%id
frequest.FILES['picture'destination=open(path,'wb+')
forchunkinf.chunks():
destination.write(chunk)
destination.close()
# return status to client
...

如何跟进上传进度?需要使用一个不同的文件上传句柄。我们打算使用UploadProgressCachedHandler。We just need the class from this snippet,not the view function which we are going to write ourself. You can add the class to a file named uploadprogresscachedhandler in your project.

这一句柄将上传进度保存到 cache,这样当我们收到客户端请求时就可以轻松地获取

为了启用这一句柄,须向 settings.py 添加如下代码

fromdjango.confimportglobal_settings
FILE_UPLOAD_HANDLERS('uploadprogresscachedhandler.UploadProgressCachedHandler'
+global_settings.FILE_UPLOAD_HANDLERS

我们还需要启用 cache 系统。我们将使用 memcached。这也放在 settings.py 里。

必须确保服务器上安装了 memcached 和 the python bindings。

我们需要在 views.py 中添加一个函数,在上传过程中,返回客户端每几秒请求获取上传进度。这一函数处理请求“/get_upload_progress?X-Progress-ID=xxxx”。进度值使用key “remoteaddress_uploadid”来存储。

django.utilssimplejson
django.core.cachecache
get_upload_progress(request):
cache_key"%s_%s"%(request.Meta['REMOTE_ADDR'],request.GET['X-Progress-ID'])
datacache.get(cache_key)
HttpResponse(simplejson.dumps(data))

猜你在找的Ajax相关文章