class CSVDownload(View):
""" Prepares CSV file version to download """
#more code here
f = StringIO.StringIO()
writer = csv.writer(f, dialect='excel')
for v in visit_list:
writer.writerow([v.idfa.idfa, v.name, v.duration, v.firstSeen, v.lastSeen, v.identifier, v.closestProximity])
f.seek(0)
response = HttpResponse(f, content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename=AdvertiserData.csv'
return response
For some reason, when opening the file in excel, the file will only output the last item in the list, see 
This leads me to believe that each row is overriding the first row. Although this shouldn't be the case. Look at these tests I have preformed in terminal.
>>> f.getvalue()
'FFAC6F6C-1B2E-47C2-8110-5E619B239FB1,PPTest1,00:00:24,2014-11-11 23:20:24.730000,2014-11-11 23:20:48.750000,nkfe-cnb7s,NEAR\r\nFFAC6F6C-1B2E-47C2-8110-5E619B239FB1,moo2,00:00:24,2014-11-11 23:20:24.730000,2014-11-11 23:20:48.750000,nkfe-cnb7s,NEAR\r\n'
This returns more than one value, with \r\n between the values.
Also, I tried
>>> print response
Content-Type: text/csv
Content-Disposition: attachment; filename=boo.csv
FFAC6F6C-1B2E-47C2-8110-5E619B239FB1,PPTest1,00:00:24,2014-11-11 23:20:24.730000,2014-11-11 23:20:48.750000,nkfe-cnb7s,NEAR
FFAC6F6C-1B2E-47C2-8110-5E619B239FB1,moo2,00:00:24,2014-11-11 23:20:24.730000,2014-11-11 23:20:48.750000,nkfe-cnb7s,NEAR
And that also showed more than one value.
I saw recently a SO thread here that discusses adding to a file here:How do you append to a file? But since I am creating this item in memory only (using stringIO), how can I get the same effect?
Thanks!
EDIT For extra information:
The visit_list is compromised of visit models:
class Visit(models.Model):
idfa = models.ForeignKey(Report)
name = models.CharField(max_length=255)
lastSeen = models.CharField(max_length=255)
duration = models.CharField(max_length=255)
firstSeen = models.CharField(max_length=255)
identifier = models.CharField(max_length=255)
closestProximity = models.CharField(max_length=255)
def __unicode__(self):
return self.name
class Meta:
verbose_name = "Visit"
verbose_name_plural = "Visits"
In this particular case, visit_list returns:
>>> visit_list
[<Visit: PPTest1>, <Visit: moo2>]
Bottom Line: I suspect you need to pass
f.getvalue()toHttpResponserather thanf.The Explanation:
HttpResponseprefers strings, although it can also be treated like a file object or accept iterators. Nevertheless,fis aStringIO.StringIOinstance and not a string per se.Consider the following setup:
Now compare
fwith the result off.getvalue():Now note the difference in your
responseobject when you pass the instance versus the string toHttpResponse:Note that the response's
_containerattribute is empty when you pass the instance toHttpResponsebut not empty when you pass thef.getvalue()string toHttpResponse.I would try this instead, then: