# views.py from django.core.files.uploadhandler import FileUploadHandler, UploadFileException # class who handles the upload class ProgressUploadHandler(FileUploadHandler): """ Download the file and store progression in the session """ def __init__(self, request=None, outPath="/tmp"): super(ProgressUploadHandler, self).__init__(request) self.progress_id = None self.cache_key = None self.request = request self.outPath = outPath self.destination = 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 = self.progress_id self.request.session['upload_progress_%s' % self.cache_key] = { 'length': self.content_length, 'uploaded' : 0 } def new_file(self, field_name, file_name, content_type, content_length, charset=None): #if not is_valid_upload(file_name): # here you can use a function to filter uploaded files. # raise UploadFileException , "forbidden file type" self.outPath = os.path.join(self.outPath, file_name) self.destination = open(self.outPath, 'wb+') pass def receive_data_chunk(self, raw_data, start): data = self.request.session['upload_progress_%s' % self.cache_key] data['uploaded'] += self.chunk_size self.request.session['upload_progress_%s' % self.cache_key] = data self.request.session.save() self.destination.write( raw_data) # data wont be passed to any other handler return None def file_complete(self, file_size): pass def upload_complete(self): try: self.destination.close() except: pass del self.request.session['upload_progress_%s' % self.cache_key] # view that display the current upload progress (json) def upload_progress(request): """ Return JSON object with information about the progress of an upload. """ 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: cache_key = "%s" % (progress_id) data = request.session.get('upload_progress_%s' % cache_key, None) return HttpResponse(simplejson.dumps(data)) else: return HttpResponseServerError('Server Error: You must provide X-Progress-ID header or query param.') # view thath launch the upload process def upload_form(request): if request.method == 'POST': outPath = os.path.join(settings.UPLOAD_ROOT, str(request.user.id)) # set your upload path here if not os.path.exists(outPath): os.makedirs(outPath) request.upload_handlers.insert(0, ProgressUploadHandler(request, outPath)) # place our custom upload in first position upload_file = request.FILES.get('file', None) # start the upload return HttpResponse("uploaded ok") # the html upload form. i use an iframe as target so the page isnt reloaded. # the upload_form view is used to receive the file
Fichier: