Reputation: 787
I am trying to convert a dictionary to csv and then download the csv file on the fly. When i return the response, I see the rows in the httpresponse. But I want it to download the content into a csv file in my local machine.
def export_csv_from_dict(data):
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="accounts.csv"'
keys = data[0].keys()
dict_writer = csv.DictWriter(response, keys)
dict_writer.writeheader()
dict_writer.writerows(data)
return response
def accounts_function(request):
# rows is a list of dictionary [{'name': 'a'}, {'name': 'b'}]
rows = get_rows_data(matched_accounts)
return data.export_csv_from_dict(rows)
I have tried many different method I saw on stackoverflow, such as filewrapper, using FileResponse, using writing to a temp file and returning it with filewrapper. Also tried using StringIO. None seems to be doing what I want to happen. Can someone explain what I am doing wrong, please. Thanks.
In chrome debugger, I see the proper content in the desired csv format. It won't pop up the download to computer window/action.
Here is now I am triggering it. Don't think this
$('#exp_csv').click(function(){
$.ajax({
'url': '/targeturl/',
'type': 'get',
data: {
'exp_csv': true,
'search_string': search
},
success: function(response){
// do something
},
error: function(){
// do something else
}
})
});
Upvotes: 0
Views: 1793
Reputation: 931
Have you tried using simple hard coded rows data? Following code based on your example should work fine. If it works, then there must be problem in populating rows data on the fly, which would need some extra information from you on how your get_rows_data function is working.
def export_csv_from_dict(self, data):
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
fieldnames = data[0].keys()
writer = csv.DictWriter(response, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
return response
def accounts_function(self, request):
rows = [{'first_name': 'Baked', 'last_name': 'Beans'},
{'first_name': 'Lovely', 'last_name': 'Spam'},
{'first_name': 'Wonderful', 'last_name': 'Spam'}]
return self.export_csv_from_dict(rows)
Upvotes: 2
Reputation: 9626
There is a sloppy error I have spotted in the base your code:
# rows is a list of dictionary [{'name': 'a'}, {'name': 'b'}]
This seems to be a fatal construction.
If you have many dictionaries with the same key, why don't you use a list which will include only the values and iterate through that list for each row?
rows = ['a', 'b',]
If the keys are different:
keys = data[0].keys()
The above code will not give you the result you expect. It will only return the key of the first dictionary in the list. You should either iterate through that list and collect the key from each dictionary separately, or construct rows
as follows:
rows = [{'name1': 'a', 'name2': 'b'},]
Upvotes: 1