Django - Create and add multiple xml to zip, and download as attachment - django

I am learner, and trying to build code to in which user has option to download the zip file that contains multiple .xlm files, which are created on the bases of database.
I have been able to create below code to download single xml file. But struggling to get multiple files packed in zipped format(for each row of database).
import xml.etree.ElementTree as ET
def export_to_xml(request):
listings = mydatabase.objects.all()
root = ET.Element('listings')
for item in listings:
price = ET.Element('price')
price.text = str(item.Name)
offer = ET.Element('offer', attrib={'id': str(item.pk)})
offer.append(price)
root.append(offer)
tree = ET.ElementTree(root)
response = HttpResponse(ET.tostring(tree.getroot()), content_type='application/xhtml+xml')
response['Content-Disposition'] = 'attachment; filename="data.xml"'
return response

Hi Got the solution by using following approach
byteStream = io.BytesIO()
with zipfile.ZipFile(byteStream, mode='w',) as zf:
# your code
zf.writestr()
response = HttpResponse(byteStream.getvalue(), content_type='application/x-zip-compressed')
response['Content-Disposition'] = "attachment; filename=finename.zip"

Related

In django, how can i upload file via url?

Hi i'm making my own webserver using django.
i just want to upload local file to django server.
i google every method but i can't get answer.
every method using form or html but i don't want to using form and html
example : from www.localfolder/example.txt to /media/examplefolder.
i don't know how to do.. any help?
this is my code.
#csrf_exempt
def download_file(request, file):
fl_path = 'media/'
filename = str(file)
fl = open(fl_path, 'r')
mime_type, _ = mimetypes.guess_type(fl_path)
response = HttpResponse(fl, content_type=mime_type)
response['Content-Disposition'] = "attachment; filename = %s" % filename
return response
What did you search for when you googled? These were the top 2 results for Django files
https://docs.djangoproject.com/en/3.0/topics/http/file-uploads/
https://docs.djangoproject.com/en/3.0/topics/files/
Seems to have everything you are looking for.

Storing and downloading files from Redis in Django Celery Queue

I'm zipping a large number of files in my app, which leads to problems with performance. So now I've decided to zip files in a separate queue, store results in Redis and make available to user as soon as the process is done. I'm storing data in Redis to make it faster, and because I don't need files to be stored on server hard drive.
Here is my task.py:
#shared_task
def zip_files(filenames, key):
compression = zipfile.ZIP_STORED
s = BytesIO()
zf = zipfile.ZipFile(s, mode="w")
for fpath in filenames:
fdir, fname = os.path.split(fpath)
zf.write(fpath, fname, compress_type=compression)
zf.close()
caches['redis'].set(hash_key, {'file':s.getvalue()})
return hash_key
And then here is my simple download view:
def folder_cache(request, folder_hash):
cache_data = caches['redis'].get(folder_hash)
if cache_data:
response = FileResponse(cache_data['file'], content_type="application/x-zip-compressed")
response['Content-Disposition'] = 'attachment; filename=hello.zip'
response['Content-Length'] = len(cache_data['file'])
return response
return HttpResponse("Cache expired.")
Problem is that I can only download a part of the file, then the download is stopped by "Network connection was lost" message. The downloaded file seems to contain a set of numbers (not binary data). But I don't know, maybe I use FileResponse wrong? Or I need to serialize data before / after putting it to Redis cache?
I also tried same code in shell, it works when I use fopen and write data from Redis cache directly to server hard drive.
Finally, I found out that I only had to wrap file data into ContentFile class. So here is the latest working code:
def folder_cache(request, folder_hash):
cache_data = caches['redis'].get(folder_hash)
if cache_data:
if (cache_data['status'] == 'complete'):
...
response = FileResponse(ContentFile(cache_data['file']), content_type="application/x-zip-compressed")
response['Content-Disposition'] = 'attachment; filename={}'.format(filename)
response['Content-Length'] = len(cache_data['file'])
return response

Django : python pandas generating blank excel

I am using pandas tool to create downloadable excel file.Excel will get it data from SQL table , which in turn will get populated depending on values entered by user.I have attached one download button in my web page to download the excel.
On clicking download button it's generating a blank excel file with sheet name and file name as Consistency Report. Can anyone point out what I am doing wrong here.
Thanks in advance
views.py
def export_excel(request):
response = HttpResponse(content_type="application/vnd.ms-excel")
response['Content-Disposition'] = 'attachment; filename=Consistency Report.xls'
fname = 'Consistency Report.xls'
cnxn = pyodbc.connect('DRIVER={SQL Server Native Client 10.0};SERVER=******;DATABASE=testing;UID=***;PWD=******')
cursor = cnxn.cursor()
cursor.execute("select * from dhm_consis_report_tbl")
columns = [column[0] for column in cursor.description]
data=cursor.fetchall()
cursor.commit()
print(columns)
for i in range(0,len(data)):
data[i]=tuple(data[i])
df = ps.DataFrame(data=data,columns=columns)
writer = ps.ExcelWriter('Consistency Report.xls',engine='xlwt')
df.to_excel(writer,sheet_name='Report')
writer.save()
return response
So, I edited my views.py and am able to generate and download excel file but the problem is that the file is now downloading at two locations; one at my project folder and one at my download folder.Also the file at download folder is empty while the one at my project folder contains data.Can anybody explain why this is happening?
Modified views.py
def export_excel(request):
response = HttpResponse(content_type="application/vnd.ms-excel;charset=utf-8")
response['Content-Disposition'] = 'attachment; filename=Consistency Report.xls'
df = ps.DataFrame.from_records(DHM_Consis_Report.objects.values('conquery_source','conquery_name','conquery_count','conquery_desc','criticality','sp_status','con_rundate','instance_id'))
print(df)
writer = ps.ExcelWriter('Consistency Report.xls',encoding='utf-8')
df.to_excel(writer,sheet_name='Report')
writer.save()
return response
Finally, I was able to generate required excel.Earlier I was creating and writing the excel with data but my HttpResponse was not getting the required data.I put the logic regarding generating excel in separate function and logic regarding downloading the generated file in separate function.This is what I did.
I know it's crude and inefficient but this works for me.If anyone has better way to do this please share.
views.py
#login_required
def consisreports(request):
cust= customername
username=None
if request.user.is_authenticated():
username=request.user.username
print(username)
table=ConsisReport(DHM_Consis_Report.objects.all())
RequestConfig(request,paginate={"per_page": 25}).configure(table)
todays=date.today()
todays=todays.strftime("%d-%m-%y")
filename="Consistency Report %s as on %s %s.xls"%(cust,str(todays),username)
colname=['Customer','Query ','Count','Desc','Criticality','Status','Rundate','Instance ID']
df = ps.DataFrame.from_records(DHM_Consis_Report.objects.values('conquery_source','conquery_name','conquery_count','conquery_desc','criticality','sp_status','con_rundate','instance_id'))
df=df[['conquery_source','conquery_name','conquery_count','conquery_desc','criticality','sp_status','con_rundate','instance_id']]
print(df)
#df.save('C:/Users/P1097/Desktop')
writer = ps.ExcelWriter(filename)
df.to_excel(writer,sheet_name='Report',index=False,engine='xlsxwriter',header=colname)
writer.save()
return render(request, 'consistency/consresult.html', {'table': table,'customername':cust})
#login_required
def export_excel(request):
custname=customername
username=None
if request.user.is_authenticated():
username=request.user.username
todays=date.today()
todays=todays.strftime("%d-%m-%y")
filename="Consistency Report %s as on %s %s.xls"%(custname,str(todays),username)
wrapper=open(filename,"rb")
cont=wrapper.read()
response = HttpResponse(cont,content_type="application/vnd.ms-excel;charset=utf-8")
response['Content-Length']=os.path.getsize(filename)
size=os.path.getsize(filename)
print(size)
wrapper.close()
response['Content-Disposition'] = 'attachment; filename= %s'%filename
return response

How to serve a django-webodt file to users?

I'm trying to allow users to export some of their database data. I am using django-webodt to create a .odt file from their data. I then am trying to allow them to download it. The file is created just fine, but when it downloads it seems to download a blank file. I think there is some difference between where the server is looking for the file and where it actually is. I was wondering how to get this to work properly? I'm relatively new to django so any help would be appreciated. The code I have is below:
def downloadBook(request, val):
template = webodt.ODFTemplate('conversion.odt')
context = dict(ideas=Book.objects.getIdeaSet(int(val)))
document = template.render(Context(context))
file_name = os.path.basename(document.name)
path_to_file = os.path.dirname(document.name)
response = HttpResponse(mimetype='application/force-download')
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
response['X-Sendfile'] = smart_str(path_to_file)
return response
I did the following and it works:
from django.template import Context
from webodt import ODFTemplate
template = ODFTemplate('template_file.odt')
context = { 'some_dict': '' }
document = template.render(Context(context))
response = HttpResponse(document.read(), mimetype='application/vnd.oasis.opendocument.text')
response['Content-Disposition'] = "attachment; filename=fancy-filename-as-you-like.odt"
document.close() # delete the document on /tmp
return response

Django download file empty

I am writing a simple function for downloading a certain file, from the server, to my machine.
The file is unique represented by its id. The file is locatd corectly, and the download is done, but the downloaded file (though named as the one on the server) is empty.
my download function looks like this:
def download_course(request, id):
course = Courses.objects.get(pk = id).course
path_to_file = 'root/cFolder'
filename = __file__ # Select your file here.
wrapper = FileWrapper(file(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/' % smart_str(course)
return response
where can i be wrong? thanks!
I answered this question here, hope it helps.
Looks like you're not sending any data (you don't even open the file).
Django has a nice wrapper for sending files (code taken from djangosnippets.org):
def send_file(request):
"""
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 = __file__ # Select your file here.
wrapper = FileWrapper(file(filename))
response = HttpResponse(wrapper, content_type='text/plain')
response['Content-Length'] = os.path.getsize(filename)
return response
so you could use something like response = HttpResponse(FileWrapper(file(path_to_file)), mimetype='application/force-download').
If you are really using lighttpd (because of the "X-Sendfile" header), you should check the server and FastCGI configuration, I guess.
Try one of these approaches:
1) Disable GZipMiddleware if you are using it;
2) Apply a patch to django/core/servers/basehttp.py described in
https://code.djangoproject.com/ticket/6027