views:

743

answers:

2

I am a new to django and python. Need some guidance in this quest.

Case: When the user hits the submit button on a form, it should display Success page and a link where they can download the results. The results are in excel file. I can create output to excel file using xlwt module and display the success page individually but not both at the same time.

What i have: I am running django1.1.1 on windows XP with python 2.6. There was similar question asked but was not able to make it work.

my success page.html has this line Download CSV File

urls.py url(r'^static/(?P.*)$', send_file),

views.py def send_file(request):

import os, tempfile, zipfile
from django.core.servers.basehttp import FileWrapper

"""                                                                         
Send a file through Django without loading the whole file into              
memory at once. The FileWrapper will turn the file object into an           
iterator for chunks of 8KB.                                                 
"""
filename = "C:/example.xls" # Select your file here.                                
wrapper = FileWrapper(file(filename),"rb")
response = HttpResponse(wrapper, content_type='text/plain')
#response['Content-Length'] = os.path.getsize(filename)
return response

When i click on the link, it gives path error

send_file() got an unexpected keyword argument 'path' Request Method: GET Request URL: localhost:8000/webinput/static/example.xls Exception Type: TypeError Exception Value:
send_file() got an unexpected keyword argument 'path'

BTW example.xls is at both the locations C:/example.xls and in static folder

Structure: webdb - Static - example.xls - Webinput urls.py views.py models.py

I have these 2 modules as well. If i use backup_to_csv it works fine but it downlods directly without the link. How to do the same when i already have a file. If there are other ways where i dont have to store file, that is fine too.

def xls_to_response(xls, fname): response = HttpResponse(mimetype="application/ms-excel") response['Content-Disposition'] = 'attachment; filename=%s' % fname xls.save(response) return response

def backup_to_csv(request,row):

response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename="backup.csv"'
writer = csv.writer(response, dialect='excel')    
#code for writing csv file go here...
for i in row:
    writer.writerow(i)
return response

Thanks in advance.

+1  A: 

In your urls.py change

urls.py url(r'^static/(?P.*)$', send_file)

to

urls.py url(r'^static/example.xls$', send_file)

In the first one, you are also passing everything after the / to the view as another parameter, but your view does not accept this parameter. another option would be to accept this parameter in the view:

def send_file(request, path):
    ...

but since the path to your xls file is hard coded, I don't think you need that.

Ofri Raviv
Thanks but it gives this errorTraceback (most recent call last): File "C:\Python26\lib\site-packages\django\core\servers\basehttp.py", line 280, in run self.finish_response() File "C:\Python26\lib\site-packages\django\core\servers\basehttp.py", line 319, in finish_response for data in self.result: File "C:\Python26\lib\site-packages\django\http\__init__.py", line 378, in next chunk = self._iterator.next() File "C:\Python26\lib\site-packages\django\core\servers\basehttp.py", line 50, in next data = self.filelike.read(self.blksize)TypeError: an integer is required
+1  A: 

Now it works but i had to change file extension from excel (.xls) to csv.

My urls.py=url(r'^static/example.txt', send_file)
My HTML link=Download CSV File
My view.py def send_file(request):

import os, tempfile, zipfile
from django.core.servers.basehttp import FileWrapper
from django.conf import settings
import mimetypes

filename     = "C:\ex2.csv" # Select your file here.
download_name ="example.csv"
wrapper      = FileWrapper(open(filename))
content_type = mimetypes.guess_type(filename)[0]
response     = HttpResponse(wrapper,content_type=content_type)
response['Content-Length']      = os.path.getsize(filename)    
response['Content-Disposition'] = "attachment; filename=%s"%download_name
return response