Django文件上传进度

时间:2012-08-28 06:51:49

标签: django file-upload progress

我已经使用Django文件上传进度流程获取进度,但收到错误pliks.upload" does not define a "UploadProgressCachedHandler" upload handler backend

我遵循的步骤是

1)创建文件夹上传并向其添加文件上传处理程序(UploadProgressCachedHandler.py)。

    from django.core.files.uploadhandler import FileUploadHandler
    from django.core.cache import cache
    class UploadProgressCachedHandler(FileUploadHandler):
        """
        Tracks progress for file uploads.
        The http post request must contain a header or query parameter, 'X-Progress-ID'
        which should contain a unique string to identify the upload to be tracked.

        Copied from:
        http://djangosnippets.org/snippets/678/

        See views.py for upload_progress function...
        """

        def __init__(self, request=None):
            super(UploadProgressCachedHandler, self).__init__(request)
            self.progress_id = None
            self.cache_key = None

        def handle_raw_input(self, input_data, META, content_length, boundary, encoding=None):
            self.content_length = content_length
            if 'X-Progress-ID' in self.request.GET :
                self.progress_id = self.request.GET['X-Progress-ID']
            elif 'X-Progress-ID' in self.request.META:
                self.progress_id = self.request.META['X-Progress-ID']
            if self.progress_id:
                self.cache_key = "%s_%s" % (self.request.META['REMOTE_ADDR'], self.progress_id )
                cache.set(self.cache_key, {
                    'length': self.content_length,
                    'uploaded' : 0
                })

        def new_file(self, field_name, file_name, content_type, content_length, charset=None):
            pass

        def receive_data_chunk(self, raw_data, start):
            if self.cache_key:
                data = cache.get(self.cache_key)
                data['uploaded'] += self.chunk_size
                cache.set(self.cache_key, data)
            return raw_data

        def file_complete(self, file_size):
            pass

        def upload_complete(self):
            if self.cache_key:
                cache.delete(self.cache_key)

2)将UploadProgressCachedHandler添加到settings.py文件中:

from django.conf import global_settings
FILE_UPLOAD_HANDLERS = ('pliks.upload.UploadProgressCachedHandler', ) + \
    global_settings.FILE_UPLOAD_HANDLERS

3)将代码添加到view.py

    from django.core.cache import cache
    from django.http import HttpResponse, HttpResponseServerError

    def upload_progress(request):
        """
        A view to report back on upload progress.
        Return JSON object with information about the progress of an upload.

        Copied from:
        http://djangosnippets.org/snippets/678/

        See upload.py for file upload handler.
        """
        #import ipdb
        #ipdb.set_trace()
        progress_id = ''
        if 'X-Progress-ID' in request.GET:
            progress_id = request.GET['X-Progress-ID']
        elif 'X-Progress-ID' in request.META:
            progress_id = request.META['X-Progress-ID']
        if progress_id:
            from django.utils import simplejson
            cache_key = "%s_%s" % (request.META['REMOTE_ADDR'], progress_id)
            data = cache.get(cache_key)
            return HttpResponse(simplejson.dumps(data))
        else:
            return HttpResponseServerError(
                'Server Error: You must provide X-Progress-ID header or query param.')

4)添加网址

url(r'^admin/upload_progress/$',
    'utils.views.upload_progress',
     name="admin-upload-progress"),

5)在模板中

   {% block extra-head %}
    <script type="text/javascript" >
    // Generate 32 char random uuid
    function gen_uuid() {
        var uuid = ""
        for (var i=0; i < 32; i++) {
            uuid += Math.floor(Math.random() * 16).toString(16);
        }
        return uuid
    }

    // Add upload progress for multipart forms.
    $(function() {
        /*
        This throws a syntax error...
        $('form[@enctype=multipart/form-data]').submit(function(){
        */
        $('#upload').submit(function(){
            // Prevent multiple submits
            if ($.data(this, 'submitted')) return false;

            var freq = 1000; // freqency of update in ms
            var uuid = gen_uuid(); // id for this upload so we can fetch progress info.
            var progress_url = '/feature/admin/upload_progress/'; // ajax view serving progress info

            // Append X-Progress-ID uuid form action
            this.action += (this.action.indexOf('?') == -1 ? '?' : '&') + 'X-Progress-ID=' + uuid;

            var $progress = $('<div id="upload-progress" class="upload-progress"></div>').
                appendTo(document.body).append('<div class="progress-container"><span class="progress-info">uploading 0%</span><div class="progress-bar"></div></div>');

            // progress bar position
            $progress.css({
                position: ($.browser.msie && $.browser.version < 7 )? 'absolute' : 'fixed',
                left: '50%', marginLeft: 0-($progress.width()/2), bottom: '20%'
            }).show();

            // Update progress bar
            function update_progress_info() {
                $progress.show();
                $.getJSON(progress_url, {'X-Progress-ID': uuid}, function(data, status){
                    if (data) {
                        var progress = parseInt(data.uploaded) / parseInt(data.length);
                        var width = $progress.find('.progress-container').width()
                        var progress_width = width * progress;
                        $progress.find('.progress-bar').width(progress_width);
                        $progress.find('.progress-info').text('uploading ' + parseInt(progress*100) + '%');
                    }
                    window.setTimeout(update_progress_info, freq);
                });
            };
            window.setTimeout(update_progress_info, freq);

            $.data(this, 'submitted', true); // mark form as submitted.
        });
    });
     </script>
    {% endblock %}

    {% block content %}
        <form id='upload' action="." enctype="multipart/form-data" method="POST">
            <table>
                {{ form.as_table }}
            </table>
            <p><input type="submit" value="Submit"></p>
        </form>
    {% endblock %}

某处我错了......

1 个答案:

答案 0 :(得分:6)

您需要提供处理程序的类名称,如果您的文件名为UploadProgressCachedHandler.py,则在此处提供模块名称。你需要使用

FILE_UPLOAD_HANDLERS = ('pliks.upload.UploadProgressCachedHandler.UploadProgressCachedHandler', ) + \
    global_settings.FILE_UPLOAD_HANDLERS

Python惯例是调用模块handlers.py而不是在它包含的类之后命名它。