Question

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

<a href="../static/example.xls">Download CSV File</a>

urls.py:

url(r'^static/(?P<path>.*)$', 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
Was it helpful?

Solution

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=<a href="../static/example.txt">Download CSV File</a>
My view.py

def send_file(request):

  import os, tempfile, zipfile
  from wsgiref.util 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

OTHER TIPS

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.

In the comments Ofri Raviv. you mentioned that its giving you a

TypeError: an integer

which is because while creating FileWrapper u are passing two parameters out of which the second one[optional] is supposed to be integer but u passed 'rb'

wrapper = FileWrapper(file(filename),"rb")

Which should actually be written as ('rb' is the parameter to File)

wrapper = FileWrapper(file(filename,"rb"))

So it was just a misalignment of braces, but makes it hard to debug sometimes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top